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
00064 ConstRandomAccessIterator& operator += (Distance distance)
00065 throw(Exception::InvalidIterator);
00066
00069 ConstRandomAccessIterator& operator -= (Distance distance)
00070 throw(Exception::InvalidIterator);
00071
00075 ConstRandomAccessIterator operator + (Distance distance) const
00076 throw(Exception::InvalidIterator);
00077
00082 ConstRandomAccessIterator operator - (Distance distance) const
00083 throw(Exception::InvalidIterator);
00084
00089 Distance operator - (const ConstRandomAccessIterator& iterator) const
00090 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00091
00095 static ConstRandomAccessIterator begin(const Container& container)
00096 throw(Exception::InvalidIterator);
00097
00101 static ConstRandomAccessIterator end(const Container& container)
00102 throw(Exception::InvalidIterator);
00103
00107 static ConstRandomAccessIterator rbegin(const Container& container)
00108 throw(Exception::InvalidIterator);
00109
00113 static ConstRandomAccessIterator rend(const Container& container)
00114 throw(Exception::InvalidIterator);
00115
00117
00121
00123 BALL_INLINE bool operator + () const { return Base::getTraits().isValid(); }
00124
00126 BALL_INLINE bool operator - () const { return !Base::getTraits().isValid(); }
00127
00134 bool operator < (const ConstRandomAccessIterator& iterator) const
00135 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00136
00144 bool operator <= (const ConstRandomAccessIterator& iterator) const
00145 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00146
00154 bool operator >= (const ConstRandomAccessIterator& iterator) const
00155 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00156
00163 bool operator > (const ConstRandomAccessIterator& iterator) const
00164 throw(Exception::InvalidIterator, Exception::IncompatibleIterators);
00165
00167
00168
00169
00175 const DataType& operator [] (Index index) const throw(Exception::InvalidIterator);
00177
00178 protected:
00179
00180 ConstRandomAccessIterator(const Container& container)
00181 : Base(container)
00182 {
00183 }
00184 };
00186
00191 template <typename Container, typename DataType, typename Position, typename Traits>
00192 ConstRandomAccessIterator<Container, DataType, Position, Traits> operator +
00193 (Distance distance, const ConstRandomAccessIterator<Container, DataType, Position, Traits>& iterator)
00194 throw(Exception::InvalidIterator)
00195 {
00196 ConstRandomAccessIterator<Container, DataType, Position, Traits> tmp_iterator(iterator);
00197 return (tmp_iterator += distance);
00198 }
00199
00204 template <typename Container, typename DataType, typename Position, typename Traits>
00205 Distance ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator -
00206 (const ConstRandomAccessIterator<Container, DataType, Position, Traits>& b) const
00207 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00208 {
00209 if (!Base::getTraits().isValid())
00210 {
00211 throw Exception::InvalidIterator(__FILE__, __LINE__);
00212 }
00213 if (!b.getTraits().isValid())
00214 {
00215 throw Exception::InvalidIterator(__FILE__, __LINE__);
00216 }
00217 if (Base::getTraits().getContainer() != b.getTraits().getContainer())
00218 {
00219 throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00220 }
00221 return Base::getTraits().getDistance(b.getTraits());
00222 }
00223
00224 template <typename Container, typename DataType, typename Position, typename Traits>
00225 ConstRandomAccessIterator<Container, DataType, Position, Traits>&
00226 ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator += (Distance distance)
00227 throw(Exception::InvalidIterator)
00228 {
00229 if (!Base::getTraits().isValid())
00230 {
00231 throw Exception::InvalidIterator(__FILE__, __LINE__);
00232 }
00233 if (distance < (Distance)0)
00234 {
00235 return (*this -= -distance);
00236 }
00237 Base::getTraits().forward(distance);
00238 return *this;
00239 }
00240
00241 template <typename Container, typename DataType, typename Position, typename Traits>
00242 ConstRandomAccessIterator<Container, DataType, Position, Traits>&
00243 ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator -= (Distance distance)
00244 throw(Exception::InvalidIterator)
00245 {
00246 if (Base::getTraits().isSingular())
00247 {
00248 throw Exception::InvalidIterator(__FILE__, __LINE__);
00249 }
00250 if (distance < (Distance)0)
00251 {
00252 return (*this += -distance);
00253 }
00254 if (Base::getTraits().isEnd() == true)
00255 {
00256 Base::getTraits().toRBegin();
00257 Base::getTraits().backward(distance - 1);
00258 }
00259 else
00260 {
00261 Base::getTraits().backward(distance);
00262 }
00263 return *this;
00264 }
00265
00266 template <typename Container, typename DataType, typename Position, typename Traits>
00267 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00268 ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator + (Distance distance) const
00269 throw(Exception::InvalidIterator)
00270 {
00271 ConstRandomAccessIterator iterator(*this);
00272 return (iterator += distance);
00273 }
00274
00275 template <typename Container, typename DataType, typename Position, typename Traits>
00276 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00277 ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator - (Distance distance) const
00278 throw(Exception::InvalidIterator)
00279 {
00280 ConstRandomAccessIterator iterator(*this);
00281 return (iterator -= distance);
00282 }
00283
00284 template <typename Container, typename DataType, typename Position, typename Traits>
00285 bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator <
00286 (const ConstRandomAccessIterator& iterator) const
00287 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00288 {
00289 if (!Base::getTraits().isValid())
00290 {
00291 throw Exception::InvalidIterator(__FILE__, __LINE__);
00292 }
00293 if (!iterator.isValid())
00294 {
00295 throw Exception::InvalidIterator(__FILE__, __LINE__);
00296 }
00297 if (Base::getTraits().getContainer() != iterator.getContainer())
00298 {
00299 throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00300 }
00301
00302 return (Base::getTraits().operator < (iterator.getTraits()));
00303 }
00304
00305 template <typename Container, typename DataType, typename Position, typename Traits>
00306 bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator <=
00307 (const ConstRandomAccessIterator& iterator) const
00308 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00309 {
00310 if (!Base::getTraits().isValid())
00311 {
00312 throw Exception::InvalidIterator(__FILE__, __LINE__);
00313 }
00314 if (!iterator.isValid())
00315 {
00316 throw Exception::InvalidIterator(__FILE__, __LINE__);
00317 }
00318 if (Base::getTraits().getContainer() != iterator.getContainer())
00319 {
00320 throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00321 }
00322 return !(Base::getTraits().operator > (iterator.getTraits()));
00323 }
00324
00325 template <typename Container, typename DataType, typename Position, typename Traits>
00326 bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator >=
00327 (const ConstRandomAccessIterator& iterator) const
00328 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00329 {
00330 if (!Base::getTraits().isValid())
00331 {
00332 throw Exception::InvalidIterator(__FILE__, __LINE__);
00333 }
00334 if (!iterator.isValid())
00335 {
00336 throw Exception::InvalidIterator(__FILE__, __LINE__);
00337 }
00338 if (Base::getTraits().getContainer() != iterator.getContainer())
00339 {
00340 throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00341 }
00342
00343 return !(Base::getTraits().operator < (iterator.getTraits()));
00344 }
00345
00346 template <typename Container, typename DataType, typename Position, typename Traits>
00347 bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator >
00348 (const ConstRandomAccessIterator& iterator) const
00349 throw(Exception::InvalidIterator, Exception::IncompatibleIterators)
00350 {
00351 if (!Base::getTraits().isValid())
00352 {
00353 throw Exception::InvalidIterator(__FILE__, __LINE__);
00354 }
00355 if (!iterator.isValid())
00356 {
00357 throw Exception::InvalidIterator(__FILE__, __LINE__);
00358 }
00359 if (Base::getTraits().getContainer() != iterator.getContainer())
00360 {
00361 throw Exception::IncompatibleIterators(__FILE__, __LINE__);
00362 }
00363
00364 return (Base::getTraits().operator > (iterator.getTraits()));
00365 }
00366
00367
00368 template <typename Container, typename DataType, typename Position, typename Traits>
00369 const DataType& ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator [] (Index index) const
00370 throw(Exception::InvalidIterator)
00371 {
00372 if (!Base::getTraits().isValid())
00373 {
00374 throw Exception::InvalidIterator(__FILE__, __LINE__);
00375 }
00376
00377 return Base::getTraits().getData(index);
00378 }
00379
00380 template <typename Container, typename DataType, typename Position, typename Traits>
00381 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00382 ConstRandomAccessIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00383 throw(Exception::InvalidIterator)
00384 {
00385 ConstRandomAccessIterator iterator(container);
00386 iterator.toBegin();
00387 return iterator;
00388 }
00389
00390 template <typename Container, typename DataType, typename Position, typename Traits>
00391 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00392 ConstRandomAccessIterator<Container, DataType, Position, Traits>::end(const Container& container)
00393 throw(Exception::InvalidIterator)
00394 {
00395 ConstRandomAccessIterator iterator(container);
00396 iterator.toEnd();
00397 return iterator;
00398 }
00399
00400 template <typename Container, typename DataType, typename Position, typename Traits>
00401 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00402 ConstRandomAccessIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00403 throw(Exception::InvalidIterator)
00404 {
00405 ConstRandomAccessIterator iterator(container);
00406 iterator.toRBegin();
00407 return iterator;
00408 }
00409
00410 template <typename Container, typename DataType, typename Position, typename Traits>
00411 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00412 ConstRandomAccessIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00413 throw(Exception::InvalidIterator)
00414 {
00415 ConstRandomAccessIterator iterator(container);
00416 iterator.toREnd();
00417 return iterator;
00418 }
00419
00424
00427 template <typename Container, typename DataType, typename Position, typename Traits>
00428 class RandomAccessIterator
00429 : public ConstRandomAccessIterator<Container, DataType, Position, Traits>
00430 {
00431 public:
00432
00436
00437 typedef DataType& reference;
00439 typedef DataType* pointer;
00441 typedef ConstRandomAccessIterator<Container, DataType, Position, Traits> Base;
00443
00447
00449 BALL_INLINE RandomAccessIterator() {}
00450
00452 BALL_INLINE RandomAccessIterator(const RandomAccessIterator& iterator)
00453 : Base(iterator)
00454 {
00455 }
00456
00458 BALL_INLINE ~RandomAccessIterator() {}
00460
00464
00465 BALL_INLINE reference operator [] (Index index) const throw(Exception::InvalidIterator) { return const_cast<reference>(Base::getTraits().getData(index)); }
00467 BALL_INLINE reference operator * () const { return const_cast<reference>(Base::getTraits().getData()); }
00469 BALL_INLINE pointer operator -> () const { return const_cast<pointer>(&Base::getTraits().getData()); }
00471
00478 static RandomAccessIterator begin(const Container& container)
00479 throw(Exception::InvalidIterator);
00480
00484 static RandomAccessIterator end(const Container& container)
00485 throw(Exception::InvalidIterator);
00486
00490 static RandomAccessIterator rbegin(const Container& container)
00491 throw(Exception::InvalidIterator);
00492
00496 static RandomAccessIterator rend(const Container& container)
00497 throw(Exception::InvalidIterator);
00499
00500 protected:
00501
00502 BALL_INLINE RandomAccessIterator(const Container& container)
00503 : Base(container)
00504 {
00505 }
00506
00507 };
00509
00510 template <typename Container, typename DataType, typename Position, typename Traits>
00511 RandomAccessIterator<Container, DataType, Position, Traits>
00512 RandomAccessIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00513 throw(Exception::InvalidIterator)
00514 {
00515 RandomAccessIterator iterator(container);
00516 iterator.toBegin();
00517 return iterator;
00518 }
00519
00520 template <typename Container, typename DataType, typename Position, typename Traits>
00521 RandomAccessIterator<Container, DataType, Position, Traits>
00522 RandomAccessIterator<Container, DataType, Position, Traits>::end(const Container& container)
00523 throw(Exception::InvalidIterator)
00524 {
00525 RandomAccessIterator iterator(container);
00526 iterator.toEnd();
00527 return iterator;
00528 }
00529
00530 template <typename Container, typename DataType, typename Position, typename Traits>
00531 RandomAccessIterator<Container, DataType, Position, Traits>
00532 RandomAccessIterator<Container, DataType, Position, Traits>::rbegin(const Container& container)
00533 throw(Exception::InvalidIterator)
00534 {
00535 RandomAccessIterator iterator(container);
00536 iterator.toRBegin();
00537 return iterator;
00538 }
00539
00540 template <typename Container, typename DataType, typename Position, typename Traits>
00541 RandomAccessIterator<Container, DataType, Position, Traits>
00542 RandomAccessIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00543 throw(Exception::InvalidIterator)
00544 {
00545 RandomAccessIterator iterator(container);
00546 iterator.toREnd();
00547 return iterator;
00548 }
00549
00550 }
00551
00552 #endif // BALL_CONCEPT_RANDOMACCESSITERATOR_H