00001
00002
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
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 }
00534
00535 #endif // BALL_CONCEPT_RANDOMACCESSITERATOR_H