00001 // "Adaptor" class which takes a class T, and presents a _guaranteed_ interface to T 00002 // This is done with templates instead of inheritance to avoid (virtual) function 00003 // call overhead, as these functions are going to be called from lots of loops, 00004 // and this way the interface gets inlined and (if everything goes well) no 00005 // overhead is incurred for using this iterator class compared to using 00006 // a 'raw' T instead... (but then you couldn't deal with different T's...) 00007 // 00008 // There is a similar example in Stroustroup, which turns an iterator into a 'checked' 00009 // iterator 00010 // 00011 // For the above to work, an implementation specific to 'T' has to be provided. 00012 // In order to allow 'T' to specify which implementation should be used, it should 00013 // provide a typename T::iterator_implementation that we can use here... 00014 // 00015 // To allow iterators over const TrkHitOnTrk and TrkHitOnTrk, 'T' should provide 00016 // a T::value_type which is either a const TrkHitOnTrk, or a TrkHitOnTrk 00017 // 00018 // BTW, the implementations tend to iterate over pointers to the valuetype, 00019 // and this class derefences the implementation to iterator over the valuetype instead... 00020 // 00021 #ifndef TRKHITONTRKITER_H 00022 #define TRKHITONTRKITER_H 00023 #include <iterator> 00024 #include <cstddef> 00025 00026 //FIXME: only works on Linux: class TrkHitOnTrkIter : public std::iterator_traits<TrkHitOnTrk *> 00027 //FIXME: only works on Linux: class TrkHitOnTrkIter : public std::random_access_iterator<const TrkHitOnTrk, ptrdiff_t> 00028 //FIXME: only works on SunOS58: class TrkHitOnTrkIter : public std::iterator<std::random_access_iterator_tag,TrkHitOnTrk> 00029 00030 class TrkHitOnTrk; 00031 00032 template <class T> 00033 class TrkHitOnTrkIter 00034 { 00035 // by using T::iterator_value_type as our value_type, we can re-use the same 00036 // code for a non-const iterator as a const iterator -- all that is needed 00037 // is a slightly different 'traits' class T to be passed here; The underlying 00038 // real iterator (the iterator_implementation) can be the same regardless of 00039 // const or non-const... 00040 00041 public: 00042 typedef std::random_access_iterator_tag iterator_category; 00043 typedef typename T::iterator_value_type value_type; 00044 typedef ptrdiff_t difference_type; 00045 typedef value_type* pointer; 00046 typedef value_type& reference; 00047 00048 typedef typename T::iterator_implementation iterator_implementation; 00049 TrkHitOnTrkIter<T>() :_i() {}; // create an invalid iter... 00050 TrkHitOnTrkIter<T>(const TrkHitOnTrkIter<T>& i) : _i(i._i) { } 00051 TrkHitOnTrkIter<T>(const iterator_implementation& i) : _i(i) { } 00052 00053 pointer get() const { return *_i; } // this function (together with * and ->) is one of the main 00054 // reasons for this class: 00055 // most (all?) underlying containers contain pointers to 00056 // TrkHitOnTrk, and we need to double-dereference to 00057 // create the illusion of something that iterates over 00058 // (const) TrkHitOnTrk instead of (const) TrkHitOnTrk* 00059 00060 pointer operator->() const { return this->get(); } 00061 reference operator*() const { return *this->get(); } 00062 00063 00064 // next: forward all usual random access iterator operations 00065 // to the underlying actual implementation... 00066 00067 TrkHitOnTrkIter<T>& operator-=(int i) { _i-=i; return *this; } 00068 TrkHitOnTrkIter<T>& operator+=(int i) { _i+=i; return *this; } 00069 00070 TrkHitOnTrkIter<T> operator-(int i) { TrkHitOnTrkIter<T> x(_i); x-=i; return x; } 00071 TrkHitOnTrkIter<T> operator+(int i) { TrkHitOnTrkIter<T> x(_i); x+=i; return x; } 00072 00073 TrkHitOnTrkIter<T>& operator--() { --_i; return *this; } // prefix -- 00074 TrkHitOnTrkIter<T>& operator++() { ++_i; return *this; } // prefix ++ 00075 00076 TrkHitOnTrkIter<T> operator--(int) { TrkHitOnTrkIter<T> x(_i); --_i; return x; } // postfix -- 00077 TrkHitOnTrkIter<T> operator++(int) { TrkHitOnTrkIter<T> x(_i); ++_i; return x; } // postfix ++ 00078 00079 ptrdiff_t operator-(const TrkHitOnTrkIter<T>& i) const { return _i - i._i; } 00080 bool operator==(const TrkHitOnTrkIter<T>& i) const { return _i==i._i; } 00081 bool operator!=(const TrkHitOnTrkIter<T>& i) const { return !operator==(i); } 00082 bool operator< (const TrkHitOnTrkIter<T>& i) const { return _i<i._i;} 00083 bool operator>=(const TrkHitOnTrkIter<T>& i) const { return !operator<(i);} 00084 bool operator> (const TrkHitOnTrkIter<T>& i) const { return _i>i._i;} 00085 bool operator<=(const TrkHitOnTrkIter<T>& i) const { return !operator>(i);} 00086 00087 private: 00088 iterator_implementation _i; 00089 }; 00090 #endif