BALL
1.4.1
|
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