00001 /* 00002 Copyright (C) 2010 - 2019 Christoph Haenisch 00003 00004 Chair of Medical Engineering (mediTEC) 00005 RWTH Aachen University 00006 Pauwelsstr. 20 00007 52074 Aachen 00008 Germany 00009 00010 See license.txt for more information. 00011 00012 Version 0.4.0 (2019-06-24) 00013 */ 00014 00020 #ifndef ITERATOR_HPP_3437312701 00021 #define ITERATOR_HPP_3437312701 00022 00023 00024 #include <cstddef> 00025 #include <iterator> 00026 #include <stdexcept> 00027 #include <typeinfo> 00028 00029 00030 namespace TRTK 00031 { 00032 00033 00035 // Iterator // 00037 00038 00039 /* Forward declarations */ 00040 00041 template <class T> 00042 class Iterator; 00043 00044 template <class T> 00045 unsigned long distance(Iterator<T> first, Iterator<T> last); 00046 00047 00148 template <class T> 00149 class Iterator : public std::iterator<std::input_iterator_tag, T> 00150 { 00151 protected: 00152 typedef void (Iterator<T>::*bool_type)() const; 00153 void safe_bool_idiom_helper_function() const; 00154 00155 public: 00156 Iterator(); 00157 Iterator(const Iterator<T> & other); 00158 virtual ~Iterator(); 00159 00160 virtual Iterator & operator=(const Iterator<T> & other); 00161 virtual T operator*() const; 00162 virtual Iterator & operator++(); 00163 virtual Iterator operator++(int); 00164 virtual bool operator==(const Iterator<T> & other) const; 00165 virtual bool operator!=(const Iterator<T> & other) const; 00166 virtual operator bool_type() const; // safe bool idiom 00167 00168 virtual bool isValid() const; 00169 const Iterator & getIterator() const; 00170 00171 friend unsigned long distance<T>(Iterator<T> first, Iterator<T> last); 00172 00173 protected: 00174 virtual Iterator * clone() const; 00175 virtual unsigned long distance(const Iterator<T> & other) const; 00176 00177 private: 00178 Iterator<T> * iterator; // is always a clone of a derived iterator (or NULL) 00179 const char * error_message; 00180 }; 00181 00182 00185 template <class T> 00186 Iterator<T>::Iterator() : iterator(NULL), error_message("Iterator<T>: Operation on uninitialized instance.") 00187 { 00188 } 00189 00190 00193 template <class T> 00194 Iterator<T>::Iterator(const Iterator<T> & other) : error_message("Iterator<T>: Operation on uninitialized instance.") 00195 { 00196 iterator = other.clone(); 00197 } 00198 00199 00202 template <class T> 00203 Iterator<T>::~Iterator() 00204 { 00205 if (iterator) delete iterator; 00206 } 00207 00208 00211 template <class T> 00212 Iterator<T> & Iterator<T>::operator=(const Iterator<T> & other) 00213 { 00214 if (&other == this) return *this; // case it = it 00215 00216 if (iterator) delete iterator; 00217 iterator = other.clone(); 00218 00219 return *this; 00220 } 00221 00222 00225 template <class T> 00226 T Iterator<T>::operator*() const 00227 { 00228 if (iterator) 00229 { 00230 return iterator->operator*(); 00231 } 00232 else 00233 { 00234 throw std::runtime_error(error_message); 00235 } 00236 } 00237 00238 00241 template <class T> 00242 Iterator<T> & Iterator<T>::operator++() 00243 { 00244 if (iterator) 00245 { 00246 return iterator->operator++(); 00247 } 00248 else 00249 { 00250 throw std::runtime_error(error_message); 00251 } 00252 } 00253 00254 00257 template <class T> 00258 Iterator<T> Iterator<T>::operator++(int) 00259 { 00260 if (iterator) 00261 { 00262 return iterator->operator++(0); 00263 } 00264 else 00265 { 00266 throw std::runtime_error(error_message); 00267 } 00268 } 00269 00270 00285 template <class T> 00286 bool Iterator<T>::operator==(const Iterator<T> & other) const 00287 { 00288 if (iterator) 00289 { 00290 return iterator->operator==(other); 00291 } 00292 else 00293 { 00294 throw std::runtime_error(error_message); 00295 } 00296 } 00297 00298 00301 template <class T> 00302 bool Iterator<T>::operator!=(const Iterator<T> & other) const 00303 { 00304 if (iterator) 00305 { 00306 return iterator->operator!=(other); 00307 } 00308 else 00309 { 00310 throw std::runtime_error(error_message); 00311 } 00312 } 00313 00314 00326 template <class T> 00327 Iterator<T>::operator typename Iterator<T>::bool_type() const // safe bool idiom 00328 { 00329 return isValid() ? &Iterator<T>::safe_bool_idiom_helper_function : NULL; 00330 } 00331 00332 00333 template <class T> 00334 void Iterator<T>::safe_bool_idiom_helper_function() const 00335 { 00336 } 00337 00338 00344 template <class T> 00345 Iterator<T> * Iterator<T>::clone() const 00346 { 00347 if (iterator == NULL) 00348 { 00349 return NULL; 00350 } 00351 else 00352 { 00353 return iterator->clone(); 00354 } 00355 } 00356 00357 00360 template <class T> 00361 const Iterator<T> & Iterator<T>::getIterator() const 00362 { 00363 return *iterator; 00364 } 00365 00366 00385 template <class T> 00386 bool Iterator<T>::isValid() const 00387 { 00388 return iterator != NULL; 00389 } 00390 00391 00398 template <class T> 00399 unsigned long Iterator<T>::distance(const Iterator<T> & other) const 00400 { 00401 if (iterator) 00402 { 00403 return iterator->distance(other); 00404 } 00405 else 00406 { 00407 throw std::runtime_error(error_message); 00408 } 00409 } 00410 00411 00420 template <class T> 00421 unsigned long distance(const Iterator<T> first, Iterator<T> last) // friend function 00422 { 00423 return first.distance(last); 00424 } 00425 00426 00428 // IteratorAdaptor // 00430 00431 00432 /* Forward declarations */ 00433 00434 template <class T, class InputIterator> 00435 class IteratorAdapter; 00436 00437 template <class T, class InputIterator> 00438 unsigned long distance(IteratorAdapter<T, InputIterator> first, IteratorAdapter<T, InputIterator> last); 00439 00440 00480 template <class T, class InputIterator> 00481 class IteratorAdapter : public Iterator<T> 00482 { 00483 protected: 00484 typedef Iterator<T> super; 00485 00486 public: 00487 IteratorAdapter(); 00488 IteratorAdapter(InputIterator iterator); 00489 IteratorAdapter(const IteratorAdapter<T, InputIterator> & other); 00490 ~IteratorAdapter(); 00491 00492 IteratorAdapter & operator=(const Iterator<T> & other); 00493 IteratorAdapter & operator=(const IteratorAdapter<T, InputIterator> & other); 00494 T operator*() const; 00495 Iterator<T> & operator++(); 00496 Iterator<T> operator++(int); 00497 bool operator==(const Iterator<T> & other) const; 00498 bool operator!=(const Iterator<T> & other) const; 00499 operator typename Iterator<T>::bool_type() const; 00500 00501 bool isValid() const; 00502 00503 friend unsigned long TRTK::distance<T, InputIterator>(IteratorAdapter<T, InputIterator> first, IteratorAdapter<T, InputIterator> last); 00504 00505 protected: 00506 Iterator<T> * clone() const; 00507 unsigned long distance(const Iterator<T> & other) const; 00508 00509 private: 00510 InputIterator iterator; 00511 bool valid; 00512 }; 00513 00514 00517 template <class T, class InputIterator> 00518 IteratorAdapter<T, InputIterator>::IteratorAdapter() : iterator(InputIterator()), valid(false) 00519 { 00520 } 00521 00522 00525 template <class T, class InputIterator> 00526 IteratorAdapter<T, InputIterator>::IteratorAdapter(InputIterator iterator) : iterator(iterator), valid(true) 00527 { 00528 } 00529 00530 00533 template <class T, class InputIterator> 00534 IteratorAdapter<T, InputIterator>::IteratorAdapter(const IteratorAdapter<T, InputIterator> & other) : iterator(other.iterator), valid(other.valid) 00535 { 00536 } 00537 00538 00541 template <class T, class InputIterator> 00542 IteratorAdapter<T, InputIterator>::~IteratorAdapter() 00543 { 00544 } 00545 00546 00549 template <class T, class InputIterator> 00550 IteratorAdapter<T, InputIterator> & IteratorAdapter<T, InputIterator>::operator=(const Iterator<T> & other) 00551 { 00552 // The case it = it is handled in the overloaded function below. 00553 00554 try 00555 { 00556 // Is 'other.iterator' of type 'IteratorAdapter'? 00557 const IteratorAdapter<T, InputIterator> & iteratorAdapter = dynamic_cast<const IteratorAdapter<T, InputIterator> &>(other.getIterator()); 00558 iterator = iteratorAdapter.iterator; 00559 valid = iteratorAdapter.valid; 00560 } 00561 catch (std::bad_cast &) 00562 { 00563 throw std::runtime_error("IteratorAdapter: Iterator types do not match"); 00564 } 00565 00566 return *this; 00567 } 00568 00569 00572 template <class T, class InputIterator> 00573 IteratorAdapter<T, InputIterator> & IteratorAdapter<T, InputIterator>::operator=(const IteratorAdapter<T, InputIterator> & other) 00574 { 00575 if (&other == this) return *this; // case it = it 00576 00577 iterator = other.iterator; 00578 valid = other.valid; 00579 return *this; 00580 } 00581 00582 00585 template <class T, class InputIterator> 00586 T IteratorAdapter<T, InputIterator>::operator*() const 00587 { 00588 return *iterator; 00589 } 00590 00591 00594 template <class T, class InputIterator> 00595 Iterator<T> & IteratorAdapter<T, InputIterator>::operator++() 00596 { 00597 ++iterator; 00598 return *this; 00599 } 00600 00601 00604 template <class T, class InputIterator> 00605 Iterator<T> IteratorAdapter<T, InputIterator>::operator++(int) 00606 { 00607 Iterator<T> temporary_iterator = *this; 00608 ++iterator; 00609 return temporary_iterator; 00610 } 00611 00612 00615 template <class T, class InputIterator> 00616 bool IteratorAdapter<T, InputIterator>::operator==(const Iterator<T> & other) const 00617 { 00618 try 00619 { 00620 // Is 'other' of type 'IteratorAdapter'? 00621 const IteratorAdapter<T, InputIterator> & iteratorAdapter = dynamic_cast<const IteratorAdapter<T, InputIterator> &>(other); 00622 return this->iterator == iteratorAdapter.iterator; 00623 } 00624 catch (std::bad_cast &) 00625 { 00626 // 'other' might be of type 'Iterator<T>'. So is 'other.iterator' of type 'IteratorAdapter'? 00627 try 00628 { 00629 const IteratorAdapter<T, InputIterator> & iteratorAdapter = dynamic_cast<const IteratorAdapter<T, InputIterator> &>(other.getIterator()); 00630 return this->iterator == iteratorAdapter.iterator; 00631 } 00632 catch (std::bad_cast &) 00633 { 00634 throw std::runtime_error("IteratorAdapter: Iterator types do not match"); 00635 } 00636 } 00637 } 00638 00639 00642 template <class T, class InputIterator> 00643 bool IteratorAdapter<T, InputIterator>::operator!=(const Iterator<T> & other) const 00644 { 00645 return !this->operator==(other); 00646 } 00647 00648 00662 template <class T, class InputIterator> 00663 IteratorAdapter<T, InputIterator>::operator typename Iterator<T>::bool_type() const // safe bool idiom 00664 { 00665 return isValid() ? &IteratorAdapter<T, InputIterator>::safe_bool_idiom_helper_function : NULL; 00666 } 00667 00668 00669 template <class T, class InputIterator> 00670 Iterator<T> * IteratorAdapter<T, InputIterator>::clone() const 00671 { 00672 return new IteratorAdapter<T, InputIterator>(iterator); 00673 } 00674 00675 00682 template <class T, class InputIterator> 00683 unsigned long IteratorAdapter<T, InputIterator>::distance(const Iterator<T> & other) const 00684 { 00685 using std::distance; 00686 00687 try 00688 { 00689 // Is 'other' of type 'IteratorAdapter'? 00690 const IteratorAdapter<T, InputIterator> & iteratorAdapter = dynamic_cast<const IteratorAdapter<T, InputIterator> &>(other); 00691 return (unsigned long ) distance(iterator, iteratorAdapter.iterator); 00692 } 00693 catch (std::bad_cast &) 00694 { 00695 // 'other' might be of type 'Iterator<T>'. So is 'other.iterator' of type 'IteratorAdapter'? 00696 try 00697 { 00698 const IteratorAdapter<T, InputIterator> & iteratorAdapter = dynamic_cast<const IteratorAdapter<T, InputIterator> &>(other.getIterator()); 00699 return (unsigned long) distance(iterator, iteratorAdapter.iterator); 00700 } 00701 catch (std::bad_cast &) 00702 { 00703 throw std::runtime_error("IteratorAdapter: Iterator types do not match"); 00704 } 00705 } 00706 } 00707 00708 00727 template <class T, class InputIterator> 00728 bool IteratorAdapter<T, InputIterator>::isValid() const 00729 { 00730 return valid; 00731 } 00732 00733 00742 template <class T, class InputIterator> 00743 unsigned long distance(IteratorAdapter<T, InputIterator> first, IteratorAdapter<T, InputIterator> last) // friend function 00744 { 00745 using std::distance; 00746 return distance(first.iterator, last.iterator); 00747 } 00748 00749 00764 template <class InputIterator> 00765 Iterator<typename InputIterator::value_type> make_iterator(InputIterator iterator) 00766 { 00767 return IteratorAdapter<typename InputIterator::value_type, InputIterator>(iterator); 00768 } 00769 00770 00771 } // namespace TRTK 00772 00773 00774 #endif // ITERATOR_HPP_3437312701
Documentation generated by Doxygen