BALL
1.4.1
|
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 // convenience typedef 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 } // namespace BALL 00549 00550 #endif // BALL_KERNEL_RANDOMACCESSITERATOR_H