00001
00002
00003
00004
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
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 }
00553
00554 #endif // BALL_CONCEPT_RANDOMACCESSITERATOR_H