00001 #ifndef _theplu_yat_utility_stride_iterator_ 00002 #define _theplu_yat_utility_stride_iterator_ 00003 00004 // $Id: StrideIterator.h 1797 2009-02-12 18:07:10Z peter $ 00005 00006 /* 00007 Copyright (C) 2007, 2008 Jari Häkkinen, Peter Johansson 00008 00009 This file is part of the yat library, http://dev.thep.lu.se/yat 00010 00011 The yat library is free software; you can redistribute it and/or 00012 modify it under the terms of the GNU General Public License as 00013 published by the Free Software Foundation; either version 3 of the 00014 License, or (at your option) any later version. 00015 00016 The yat library is distributed in the hope that it will be useful, 00017 but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 General Public License for more details. 00020 00021 You should have received a copy of the GNU General Public License 00022 along with yat. If not, see <http://www.gnu.org/licenses/>. 00023 */ 00024 00025 #include "iterator_traits.h" 00026 00027 #include <boost/iterator/iterator_adaptor.hpp> 00028 00029 namespace theplu { 00030 namespace yat { 00031 namespace utility { 00032 00033 // forward declaration 00034 template<typename Iter> 00035 class StrideIterator; 00036 00040 template <typename Iter> 00041 struct weighted_iterator_traits<StrideIterator<Iter> > { 00045 typedef typename weighted_iterator_traits<Iter>::type type; 00046 }; 00047 00051 template <class Iter> 00052 struct iterator_traits<StrideIterator<Iter> > { 00056 typedef typename iterator_traits<Iter>::data_reference data_reference; 00057 00061 typedef typename iterator_traits<Iter>::weight_reference weight_reference; 00062 00066 data_reference data(StrideIterator<Iter> iter) const 00067 { return iterator_traits<Iter>().data(iter.base()); } 00068 00072 weight_reference weight(StrideIterator<Iter> iter) const 00073 { return iterator_traits<Iter>().weight(iter.base()); } 00074 00075 }; 00076 00085 template<typename Iter> 00086 class StrideIterator 00087 : public boost::iterator_adaptor<StrideIterator<Iter>, Iter> 00088 { 00089 typedef boost::iterator_adaptor<StrideIterator<Iter>,Iter> super_t; 00090 00091 public: 00093 typedef Iter iterator_type; 00094 00095 /* 00097 typedef typename std::iterator_traits<Iter>::value_type value_type; 00099 typedef typename std::iterator_traits<Iter>::difference_type difference_type; 00101 typedef typename std::iterator_traits<Iter>::reference reference; 00103 typedef typename std::iterator_traits<Iter>::pointer pointer; 00105 typedef typename yat::utility::weighted_iterator_traits<Iter>::type w_type; 00106 */ 00107 00113 explicit StrideIterator(size_t stride=1) 00114 : StrideIterator::iterator_adaptor_(), stride_(stride) {} 00115 00119 explicit StrideIterator(Iter p, size_t stride=1) 00120 : StrideIterator::iterator_adaptor_(p), stride_(stride) {} 00121 00122 00126 StrideIterator(const StrideIterator& other) 00127 : StrideIterator::iterator_adaptor_(other.base()), stride_(other.stride()) 00128 {} 00129 00137 template<typename I2> 00138 StrideIterator(StrideIterator<I2> other, 00139 typename boost::enable_if_convertible<I2, Iter>::type* = 0 ) 00140 : StrideIterator::iterator_adaptor_(other.base()), 00141 stride_(other.stride()) {} 00142 00146 StrideIterator& operator=(const StrideIterator& rhs) 00147 { 00148 stride_ = rhs.stride(); 00149 this->base_reference() = rhs.base(); 00150 return *this; 00151 } 00152 00156 inline size_t stride(void) const { return stride_; } 00157 00158 private: 00159 // to give base class access to private parts 00160 friend class boost::iterator_core_access; 00161 00162 size_t stride_; 00163 00164 //typedef typename StrideIterator::iterator_adaptor_::difference_type 00165 typedef typename StrideIterator::iterator_adaptor_::difference_type 00166 difference_t; 00167 00168 void advance(typename super_t::difference_type n) 00169 { this->base_reference() += stride_*n; } 00170 00171 void decrement(void) { this->base_reference()-=stride_; } 00172 00173 template <class OtherIterator> 00174 typename super_t::difference_type 00175 distance_to(const StrideIterator<OtherIterator>& other) const 00176 { 00177 // casting to int to avoid loss of sign in numerator 00178 return (other.base() - this->base() )/static_cast<int>(stride_); 00179 } 00180 00181 void increment(void) { this->base_reference()+=stride_; } 00182 00183 }; 00184 00185 00186 00187 00188 00189 }}} // of namespace utility, yat, and theplu 00190 00191 #endif