BALL  1.4.1
randomAccessIterator.h
Go to the documentation of this file.
00001 // -*- Mode: C++; tab-width: 2; -*-
00002 // vi: set ts=2:
00003 //
00004 
00005 #ifndef BALL_CONCEPT_RANDOMACCESSITERATOR_H
00006 #define BALL_CONCEPT_RANDOMACCESSITERATOR_H
00007 
00008 #ifndef BALL_COMMON_H
00009 # include <BALL/common.h>
00010 #endif
00011 
00012 #ifndef BALL_CONCEPT_BIDIRECTIONALITERATOR_H
00013 # include <BALL/CONCEPT/bidirectionalIterator.h>
00014 #endif
00015 
00016 namespace BALL 
00017 {
00018 
00023   template <typename Container, typename DataType, typename Position, typename Traits>
00024   class ConstRandomAccessIterator
00025     : public ConstBidirectionalIterator<Container, DataType, Position, Traits>
00026   {
00027     public:
00028 
00032 
00034     typedef std::random_access_iterator_tag iterator_category;
00035     // convenience typedef
00036     typedef ConstBidirectionalIterator<Container, DataType, Position, Traits> Base;
00038 
00042 
00044     BALL_INLINE ConstRandomAccessIterator()  {}
00045   
00047     BALL_INLINE ConstRandomAccessIterator(const ConstRandomAccessIterator& iterator) 
00048       : Base(iterator)
00049     {
00050     }
00051 
00053     BALL_INLINE ~ConstRandomAccessIterator()  {}
00055 
00056 
00057 
00061     
00065     ConstRandomAccessIterator& operator += (Distance distance);
00066 
00070     ConstRandomAccessIterator& operator -= (Distance distance);
00071 
00076     ConstRandomAccessIterator operator + (Distance distance) const;
00077 
00083     ConstRandomAccessIterator operator - (Distance distance) const;
00084 
00091     Distance operator - (const ConstRandomAccessIterator& iterator) const;
00092 
00097     static ConstRandomAccessIterator begin(const Container& container);
00098 
00103     static ConstRandomAccessIterator end(const Container& container);
00104 
00109     static ConstRandomAccessIterator rbegin(const Container& container);
00110 
00115     static ConstRandomAccessIterator rend(const Container& container);
00116 
00118 
00122 
00124     BALL_INLINE bool operator + () const  { return Base::getTraits().isValid(); }
00125 
00127     BALL_INLINE bool operator - () const  { return !Base::getTraits().isValid(); }
00128 
00135     bool operator < (const ConstRandomAccessIterator& iterator) const;
00136 
00144     bool operator <= (const ConstRandomAccessIterator& iterator) const;
00145 
00153     bool operator >= (const ConstRandomAccessIterator& iterator) const;
00154 
00161     bool operator > (const ConstRandomAccessIterator& iterator) const;
00162 
00164 
00165       
00166 
00173     const DataType& operator [] (Index index) const;
00175 
00176     protected:
00177 
00178     ConstRandomAccessIterator(const Container& container) 
00179       : Base(container)
00180     {
00181     }
00182   };
00184   
00190   template <typename Container, typename DataType, typename Position, typename Traits>
00191   ConstRandomAccessIterator<Container, DataType, Position, Traits> operator + 
00192     (Distance distance, const ConstRandomAccessIterator<Container, DataType, Position, Traits>& iterator) 
00193   {
00194     ConstRandomAccessIterator<Container, DataType, Position, Traits> tmp_iterator(iterator);
00195     return (tmp_iterator += distance);
00196   }
00197 
00203   template <typename Container, typename DataType, typename Position, typename Traits>
00204   Distance ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator -
00205     (const ConstRandomAccessIterator<Container, DataType, Position, Traits>& b) const
00206   {
00207     if (!Base::getTraits().isValid())
00208     {
00209       throw Exception::InvalidIterator(__FILE__, __LINE__);
00210     }
00211     if (!b.getTraits().isValid())
00212     {
00213       throw Exception::InvalidIterator(__FILE__, __LINE__);
00214     }
00215     if (Base::getTraits().getContainer() != b.getTraits().getContainer())
00216     {
00217       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00218     }
00219     return Base::getTraits().getDistance(b.getTraits());
00220   }
00221 
00222   template <typename Container, typename DataType, typename Position, typename Traits>
00223   ConstRandomAccessIterator<Container, DataType, Position, Traits>&
00224     ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator += (Distance distance)
00225   {
00226     if (!Base::getTraits().isValid())
00227     {
00228       throw Exception::InvalidIterator(__FILE__, __LINE__);
00229     }
00230     if (distance < (Distance)0)
00231     {
00232       return (*this -= -distance);
00233     }
00234     Base::getTraits().forward(distance);
00235     return *this;
00236   }
00237 
00238   template <typename Container, typename DataType, typename Position, typename Traits>
00239   ConstRandomAccessIterator<Container, DataType, Position, Traits>&
00240     ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator -= (Distance distance)
00241   {
00242     if (Base::getTraits().isSingular())
00243     {
00244       throw Exception::InvalidIterator(__FILE__, __LINE__);
00245     }
00246     if (distance < (Distance)0)
00247     {
00248       return (*this += -distance);
00249     }
00250     if (Base::getTraits().isEnd() == true)
00251     {
00252       Base::getTraits().toRBegin();
00253       Base::getTraits().backward(distance - 1);
00254     }
00255     else 
00256     {
00257       Base::getTraits().backward(distance);
00258     }
00259     return *this;
00260   }
00261 
00262   template <typename Container, typename DataType, typename Position, typename Traits>
00263   ConstRandomAccessIterator<Container, DataType, Position, Traits>
00264     ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator + (Distance distance) const
00265   {
00266     ConstRandomAccessIterator iterator(*this);
00267     return (iterator += distance);
00268   }
00269 
00270   template <typename Container, typename DataType, typename Position, typename Traits>
00271   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00272     ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator - (Distance distance) const
00273   {
00274     ConstRandomAccessIterator iterator(*this);
00275     return (iterator -= distance);
00276   }
00277 
00278   template <typename Container, typename DataType, typename Position, typename Traits>
00279   bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator < 
00280     (const ConstRandomAccessIterator& iterator) const
00281   {
00282     if (!Base::getTraits().isValid())
00283     {
00284       throw Exception::InvalidIterator(__FILE__, __LINE__);
00285     }
00286     if (!iterator.isValid())
00287     {
00288       throw Exception::InvalidIterator(__FILE__, __LINE__);       
00289     }
00290     if (Base::getTraits().getContainer() != iterator.getContainer())
00291     {
00292       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00293     }
00294 
00295     return (Base::getTraits().operator < (iterator.getTraits()));
00296   }
00297 
00298   template <typename Container, typename DataType, typename Position, typename Traits>
00299   bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator <= 
00300     (const ConstRandomAccessIterator& iterator) const
00301   {
00302     if (!Base::getTraits().isValid())
00303     {
00304       throw Exception::InvalidIterator(__FILE__, __LINE__);
00305     }
00306     if (!iterator.isValid())
00307     {
00308       throw Exception::InvalidIterator(__FILE__, __LINE__);
00309     }
00310     if (Base::getTraits().getContainer() != iterator.getContainer())
00311     {
00312       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00313     }
00314     return !(Base::getTraits().operator > (iterator.getTraits()));
00315   }
00316 
00317   template <typename Container, typename DataType, typename Position, typename Traits>
00318   bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator >= 
00319     (const ConstRandomAccessIterator& iterator) const
00320   {
00321     if (!Base::getTraits().isValid())
00322     {
00323       throw Exception::InvalidIterator(__FILE__, __LINE__);
00324     }
00325     if (!iterator.isValid())
00326     {
00327       throw Exception::InvalidIterator(__FILE__, __LINE__);
00328     }
00329     if (Base::getTraits().getContainer() != iterator.getContainer())
00330     {
00331       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00332     }
00333 
00334     return !(Base::getTraits().operator < (iterator.getTraits()));
00335   }
00336 
00337   template <typename Container, typename DataType, typename Position, typename Traits>
00338   bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator > 
00339     (const ConstRandomAccessIterator& iterator) const
00340   {
00341     if (!Base::getTraits().isValid())
00342     {
00343       throw Exception::InvalidIterator(__FILE__, __LINE__);
00344     }
00345     if (!iterator.isValid())
00346     {
00347       throw Exception::InvalidIterator(__FILE__, __LINE__);
00348     }
00349     if (Base::getTraits().getContainer() != iterator.getContainer())
00350     {
00351       throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00352     }
00353 
00354     return (Base::getTraits().operator > (iterator.getTraits()));
00355   }
00356 
00357   
00358   template <typename Container, typename DataType, typename Position, typename Traits>
00359   const DataType& ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator [] (Index index) const
00360   {
00361     if (!Base::getTraits().isValid())
00362     {
00363       throw Exception::InvalidIterator(__FILE__, __LINE__);
00364     }
00365 
00366     return Base::getTraits().getData(index);
00367   }
00368 
00369   template <typename Container, typename DataType, typename Position, typename Traits>
00370   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00371     ConstRandomAccessIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00372   {
00373     ConstRandomAccessIterator iterator(container);
00374     iterator.toBegin();
00375     return iterator;
00376   }
00377 
00378   template <typename Container, typename DataType, typename Position, typename Traits>
00379   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00380     ConstRandomAccessIterator<Container, DataType, Position, Traits>::end(const Container& container)
00381   {
00382     ConstRandomAccessIterator iterator(container);
00383     iterator.toEnd();
00384     return iterator;
00385   }
00386 
00387   template <typename Container, typename DataType, typename Position, typename Traits>
00388   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00389     ConstRandomAccessIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00390   {
00391     ConstRandomAccessIterator iterator(container);
00392     iterator.toRBegin();
00393     return iterator;
00394   }
00395 
00396   template <typename Container, typename DataType, typename Position, typename Traits>
00397   ConstRandomAccessIterator<Container, DataType, Position, Traits> 
00398     ConstRandomAccessIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00399   {
00400     ConstRandomAccessIterator iterator(container);
00401     iterator.toREnd();
00402     return iterator;
00403   }
00404 
00409 
00412   template <typename Container, typename DataType, typename Position, typename Traits>
00413   class RandomAccessIterator
00414     : public ConstRandomAccessIterator<Container, DataType, Position, Traits>
00415   {
00416     public:
00417 
00421 
00422     typedef DataType& reference;
00424     typedef DataType* pointer;
00426     typedef ConstRandomAccessIterator<Container, DataType, Position, Traits> Base;
00428 
00432 
00434     BALL_INLINE RandomAccessIterator()  {}
00435   
00437     BALL_INLINE RandomAccessIterator(const RandomAccessIterator& iterator) 
00438       : Base(iterator)
00439     {
00440     }
00441 
00443     BALL_INLINE ~RandomAccessIterator()  {}
00445 
00452     BALL_INLINE reference operator [] (Index index) const { return const_cast<reference>(Base::getTraits().getData(index)); }
00454     BALL_INLINE reference operator * () const  { return const_cast<reference>(Base::getTraits().getData()); }
00456     BALL_INLINE pointer operator -> () const  { return const_cast<pointer>(&Base::getTraits().getData()); }
00458 
00466     static RandomAccessIterator begin(const Container& container);
00467 
00472     static RandomAccessIterator end(const Container& container);
00473 
00478     static RandomAccessIterator rbegin(const Container& container);
00479 
00484     static RandomAccessIterator rend(const Container& container);
00486 
00487     protected:
00488 
00489     BALL_INLINE RandomAccessIterator(const Container& container) 
00490       : Base(container)
00491     {
00492     }
00493 
00494   };
00496   
00497   template <typename Container, typename DataType, typename Position, typename Traits>
00498   RandomAccessIterator<Container, DataType, Position, Traits> 
00499     RandomAccessIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00500   {
00501     RandomAccessIterator iterator(container);
00502     iterator.toBegin();
00503     return iterator;
00504   }
00505 
00506   template <typename Container, typename DataType, typename Position, typename Traits>
00507   RandomAccessIterator<Container, DataType, Position, Traits> 
00508     RandomAccessIterator<Container, DataType, Position, Traits>::end(const Container& container)
00509   {
00510     RandomAccessIterator iterator(container);
00511     iterator.toEnd();
00512     return iterator;
00513   }
00514 
00515   template <typename Container, typename DataType, typename Position, typename Traits>
00516   RandomAccessIterator<Container, DataType, Position, Traits> 
00517     RandomAccessIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00518   {
00519     RandomAccessIterator iterator(container);
00520     iterator.toRBegin();
00521     return iterator;
00522   }
00523 
00524   template <typename Container, typename DataType, typename Position, typename Traits>
00525   RandomAccessIterator<Container, DataType, Position, Traits> 
00526     RandomAccessIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00527   {
00528     RandomAccessIterator iterator(container);
00529     iterator.toREnd();
00530     return iterator;
00531   }
00532 
00533 } // namespace BALL 
00534 
00535 #endif // BALL_CONCEPT_RANDOMACCESSITERATOR_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines