00001 #ifndef BALL_LINALG_RANDOMACCESSITERATOR_H
00002 #define BALL_LINALG_RANDOMACCESSITERATOR_H
00003
00004 #ifndef BALL_CONCEPT_BIDIRECTIONALITERATOR_H
00005 #include <BALL/CONCEPT/bidirectionalIterator.h>
00006 #endif
00007
00008 namespace BALL
00009 {
00011 typedef int Distance;
00013 typedef int Index;
00014
00019 template <typename Container, typename DataType, typename Position, typename Traits>
00020 class ConstRandomAccessIterator
00021 : public ConstBidirectionalIterator<Container, DataType, Position, Traits>
00022 {
00023 public:
00024
00028
00030 typedef std::random_access_iterator_tag iterator_category;
00031
00032 typedef ConstBidirectionalIterator<Container, DataType, Position, Traits> Base;
00034
00038
00040 ConstRandomAccessIterator() {}
00041
00043 ConstRandomAccessIterator(const ConstRandomAccessIterator& iterator)
00044 : Base(iterator)
00045 {
00046 }
00047
00049 ~ConstRandomAccessIterator() {}
00051
00052
00053
00057
00061 ConstRandomAccessIterator& operator += (Distance distance);
00062
00066 ConstRandomAccessIterator& operator -= (Distance distance);
00067
00072 ConstRandomAccessIterator operator + (Distance distance) const;
00073
00079 ConstRandomAccessIterator operator - (Distance distance) const;
00080
00087 Distance operator - (const ConstRandomAccessIterator& iterator) const;
00088
00093 static ConstRandomAccessIterator begin(const Container& container);
00094
00099 static ConstRandomAccessIterator end(const Container& container);
00100
00105 static ConstRandomAccessIterator rbegin(const Container& container);
00106
00111 static ConstRandomAccessIterator rend(const Container& container);
00112
00114
00118
00120 bool operator + () const { return Base::getTraits().isValid(); }
00121
00123 bool operator - () const { return !Base::getTraits().isValid(); }
00124
00131 bool operator < (const ConstRandomAccessIterator& iterator) const;
00132
00140 bool operator <= (const ConstRandomAccessIterator& iterator) const;
00141
00149 bool operator >= (const ConstRandomAccessIterator& iterator) const;
00150
00157 bool operator > (const ConstRandomAccessIterator& iterator) const;
00158
00160
00161
00162
00169 const DataType& operator [] (Index index) const;
00171
00172 protected:
00173
00174 ConstRandomAccessIterator(const Container& container)
00175 : Base(container)
00176 {
00177 }
00178 };
00180
00186 template <typename Container, typename DataType, typename Position, typename Traits>
00187 ConstRandomAccessIterator<Container, DataType, Position, Traits> operator +
00188 (Distance distance, const ConstRandomAccessIterator<Container, DataType, Position, Traits>& iterator)
00189 {
00190 ConstRandomAccessIterator<Container, DataType, Position, Traits> tmp_iterator(iterator);
00191 return (tmp_iterator += distance);
00192 }
00193
00200 template <typename Container, typename DataType, typename Position, typename Traits>
00201 Distance ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator -
00202 (const ConstRandomAccessIterator<Container, DataType, Position, Traits>& b) const
00203 {
00204 if (!Base::getTraits().isValid())
00205 {
00206 Exception::InvalidIterator e;
00207 throw e;
00208 }
00209 if (!b.getTraits().isValid())
00210 {
00211 Exception::InvalidIterator e;
00212 throw e;
00213 }
00214 if (Base::getTraits().getContainer() != b.getTraits().getContainer())
00215 {
00216 Exception::IncompatibleIterators e;
00217 throw e;
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 Exception::InvalidIterator e;
00229 throw e;
00230 }
00231 if (distance < (Distance)0)
00232 {
00233 return (*this -= -distance);
00234 }
00235 Base::getTraits().forward(distance);
00236 return *this;
00237 }
00238
00239 template <typename Container, typename DataType, typename Position, typename Traits>
00240 ConstRandomAccessIterator<Container, DataType, Position, Traits>&
00241 ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator -= (Distance distance)
00242 {
00243 if (Base::getTraits().isSingular())
00244 {
00245 Exception::InvalidIterator e;
00246 throw e;
00247 }
00248 if (distance < (Distance)0)
00249 {
00250 return (*this += -distance);
00251 }
00252 if (Base::getTraits().isEnd() == true)
00253 {
00254 Base::getTraits().toRBegin();
00255 Base::getTraits().backward(distance - 1);
00256 }
00257 else
00258 {
00259 Base::getTraits().backward(distance);
00260 }
00261 return *this;
00262 }
00263
00264 template <typename Container, typename DataType, typename Position, typename Traits>
00265 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00266 ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator + (Distance distance) const
00267 {
00268 ConstRandomAccessIterator iterator(*this);
00269 return (iterator += distance);
00270 }
00271
00272 template <typename Container, typename DataType, typename Position, typename Traits>
00273 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00274 ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator - (Distance distance) const
00275 {
00276 ConstRandomAccessIterator iterator(*this);
00277 return (iterator -= distance);
00278 }
00279
00280 template <typename Container, typename DataType, typename Position, typename Traits>
00281 bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator <
00282 (const ConstRandomAccessIterator& iterator) const
00283 {
00284 if (!Base::getTraits().isValid())
00285 {
00286 Exception::InvalidIterator e;
00287 throw e;
00288 }
00289 if (!iterator.isValid())
00290 {
00291 Exception::InvalidIterator e;
00292 throw e;
00293 }
00294 if (Base::getTraits().getContainer() != iterator.getContainer())
00295 {
00296 Exception::IncompatibleIterators e;
00297 throw e;
00298 }
00299
00300 return (Base::getTraits().operator < (iterator.getTraits()));
00301 }
00302
00303 template <typename Container, typename DataType, typename Position, typename Traits>
00304 bool ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator <=
00305 (const ConstRandomAccessIterator& iterator) const
00306 {
00307 if (!Base::getTraits().isValid())
00308 {
00309 Exception::InvalidIterator e;
00310 throw e;
00311 }
00312 if (!iterator.isValid())
00313 {
00314 Exception::InvalidIterator e;
00315 throw e;
00316 }
00317 if (Base::getTraits().getContainer() != iterator.getContainer())
00318 {
00319 Exception::IncompatibleIterators e;
00320 throw e;
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 {
00329 if (!Base::getTraits().isValid())
00330 {
00331 Exception::InvalidIterator e;
00332 throw e;
00333 }
00334 if (!iterator.isValid())
00335 {
00336 Exception::InvalidIterator e;
00337 throw e;
00338 }
00339 if (Base::getTraits().getContainer() != iterator.getContainer())
00340 {
00341 Exception::IncompatibleIterators e;
00342 throw e;
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 {
00352 if (!Base::getTraits().isValid())
00353 {
00354 Exception::InvalidIterator e;
00355 throw e;
00356 }
00357 if (!iterator.isValid())
00358 {
00359 Exception::InvalidIterator e;
00360 throw e;
00361 }
00362 if (Base::getTraits().getContainer() != iterator.getContainer())
00363 {
00364 Exception::IncompatibleIterators e;
00365 throw e;
00366 }
00367
00368 return (Base::getTraits().operator > (iterator.getTraits()));
00369 }
00370
00371
00372 template <typename Container, typename DataType, typename Position, typename Traits>
00373 const DataType& ConstRandomAccessIterator<Container, DataType, Position, Traits>::operator [] (Index index) const
00374 {
00375 if (!Base::getTraits().isValid())
00376 {
00377 Exception::InvalidIterator e;
00378 throw e;
00379 }
00380
00381 return Base::getTraits().getData(index);
00382 }
00383
00384 template <typename Container, typename DataType, typename Position, typename Traits>
00385 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00386 ConstRandomAccessIterator<Container, DataType, Position, Traits>::begin(const Container& container)
00387 {
00388 ConstRandomAccessIterator iterator(container);
00389 iterator.toBegin();
00390 return iterator;
00391 }
00392
00393 template <typename Container, typename DataType, typename Position, typename Traits>
00394 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00395 ConstRandomAccessIterator<Container, DataType, Position, Traits>::end(const Container& container)
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 {
00406 ConstRandomAccessIterator iterator(container);
00407 iterator.toRBegin();
00408 return iterator;
00409 }
00410
00411 template <typename Container, typename DataType, typename Position, typename Traits>
00412 ConstRandomAccessIterator<Container, DataType, Position, Traits>
00413 ConstRandomAccessIterator<Container, DataType, Position, Traits>::rend(const Container& container)
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 RandomAccessIterator() {}
00450
00452 RandomAccessIterator(const RandomAccessIterator& iterator)
00453 : Base(iterator)
00454 {
00455 }
00456
00458 ~RandomAccessIterator() {}
00460
00467 reference operator [] (Index index) const { return const_cast<reference>(Base::getTraits().getData(index)); }
00469 reference operator * () const { return const_cast<reference>(Base::getTraits().getData()); }
00471 pointer operator -> () const { return const_cast<pointer>(&Base::getTraits().getData()); }
00473
00481 static RandomAccessIterator begin(const Container& container);
00482
00487 static RandomAccessIterator end(const Container& container);
00488
00493 static RandomAccessIterator rbegin(const Container& container);
00494
00499 static RandomAccessIterator rend(const Container& container);
00501
00502 protected:
00503
00504 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 {
00516 RandomAccessIterator iterator(container);
00517 iterator.toBegin();
00518 return iterator;
00519 }
00520
00521 template <typename Container, typename DataType, typename Position, typename Traits>
00522 RandomAccessIterator<Container, DataType, Position, Traits>
00523 RandomAccessIterator<Container, DataType, Position, Traits>::end(const Container& container)
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 {
00534 RandomAccessIterator iterator(container);
00535 iterator.toRBegin();
00536 return iterator;
00537 }
00538
00539 template <typename Container, typename DataType, typename Position, typename Traits>
00540 RandomAccessIterator<Container, DataType, Position, Traits>
00541 RandomAccessIterator<Container, DataType, Position, Traits>::rend(const Container& container)
00542 {
00543 RandomAccessIterator iterator(container);
00544 iterator.toREnd();
00545 return iterator;
00546 }
00547
00548 }
00549
00550 #endif // BALL_KERNEL_RANDOMACCESSITERATOR_H