00001
00002
00003 #ifndef DUNE_GENERICITERATOR_HH
00004 #define DUNE_GENERICITERATOR_HH
00005
00006 #include <dune/common/iteratorfacades.hh>
00007 #include <cassert>
00008
00009 namespace Dune {
00010
00083 template<class R>
00084 struct const_reference
00085 {
00086 typedef const R type;
00087 };
00088
00089 template<class R>
00090 struct const_reference<const R>
00091 {
00092 typedef const R type;
00093 };
00094
00095 template<class R>
00096 struct const_reference<R&>
00097 {
00098 typedef const R& type;
00099 };
00100
00101 template<class R>
00102 struct const_reference<const R&>
00103 {
00104 typedef const R& type;
00105 };
00106
00112 template<class R>
00113 struct mutable_reference
00114 {
00115 typedef R type;
00116 };
00117
00118 template<class R>
00119 struct mutable_reference<const R>
00120 {
00121 typedef R type;
00122 };
00123
00124 template<class R>
00125 struct mutable_reference<R&>
00126 {
00127 typedef R& type;
00128 };
00129
00130 template<class R>
00131 struct mutable_reference<const R&>
00132 {
00133 typedef R& type;
00134 };
00135
00147 template<class C, class T, class R=T&, class D = std::ptrdiff_t,
00148 template<class,class,class,class> class IteratorFacade=RandomAccessIteratorFacade>
00149 class GenericIterator :
00150 public IteratorFacade<GenericIterator<C,T,R,D,IteratorFacade>,T,R,D>
00151 {
00152 friend class GenericIterator<typename std::remove_const<C>::type, typename std::remove_const<T>::type, typename mutable_reference<R>::type, D, IteratorFacade>;
00153 friend class GenericIterator<const typename std::remove_const<C>::type, const typename std::remove_const<T>::type, typename const_reference<R>::type, D, IteratorFacade>;
00154
00155 typedef GenericIterator<typename std::remove_const<C>::type, typename std::remove_const<T>::type, typename mutable_reference<R>::type, D, IteratorFacade> MutableIterator;
00156 typedef GenericIterator<const typename std::remove_const<C>::type, const typename std::remove_const<T>::type, typename const_reference<R>::type, D, IteratorFacade> ConstIterator;
00157
00158 public:
00159
00168 typedef C Container;
00169
00175 typedef T Value;
00176
00180 typedef D DifferenceType;
00181
00185 typedef R Reference;
00186
00187
00188 GenericIterator() : container_(0), position_(0)
00189 {}
00190
00198 GenericIterator(Container& cont, DifferenceType pos)
00199 : container_(&cont), position_(pos)
00200 {}
00201
00209 GenericIterator(const MutableIterator& other) : container_(other.container_), position_(other.position_)
00210 {}
00211
00221 GenericIterator(const ConstIterator& other) : container_(other.container_), position_(other.position_)
00222 {}
00223
00224
00225 bool equals(const MutableIterator & other) const
00226 {
00227 return position_ == other.position_ && container_ == other.container_;
00228 }
00229
00230 bool equals(const ConstIterator & other) const
00231 {
00232 return position_ == other.position_ && container_ == other.container_;
00233 }
00234
00235 Reference dereference() const {
00236 return container_->operator[](position_);
00237 }
00238
00239 void increment(){
00240 ++position_;
00241 }
00242
00243
00244 void decrement(){
00245 --position_;
00246 }
00247
00248
00249 Reference elementAt(DifferenceType i) const {
00250 return container_->operator[](position_+i);
00251 }
00252
00253 void advance(DifferenceType n){
00254 position_=position_+n;
00255 }
00256
00257 DifferenceType distanceTo(const MutableIterator& other) const
00258 {
00259 assert(other.container_==container_);
00260 return other.position_ - position_;
00261 }
00262
00263 DifferenceType distanceTo(const ConstIterator& other) const
00264 {
00265 assert(other.container_==container_);
00266 return other.position_ - position_;
00267 }
00268
00269 private:
00270 Container *container_;
00271 DifferenceType position_;
00272 };
00273
00276 }
00277
00278 #endif