00001 #ifndef _theplu_yat_utility_stride_iterator_
00002 #define _theplu_yat_utility_stride_iterator_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <boost/concept_check.hpp>
00027 #include <boost/iterator/iterator_adaptor.hpp>
00028
00029 namespace theplu {
00030 namespace yat {
00031 namespace utility {
00032
00044 template<typename RandomAccessIterator>
00045 class StrideIterator
00046 : public boost::iterator_adaptor<StrideIterator<RandomAccessIterator>
00047 , RandomAccessIterator
00048 , boost::use_default
00049 , typename std::iterator_traits<RandomAccessIterator>::iterator_category>
00050 {
00051 typedef boost::iterator_adaptor<StrideIterator<RandomAccessIterator>,
00052 RandomAccessIterator,
00053 boost::use_default,
00054 typename std::iterator_traits<RandomAccessIterator>::iterator_category>
00055 super_t;
00056
00057 public:
00059 typedef RandomAccessIterator iterator_type;
00060
00066 explicit StrideIterator(size_t stride=1)
00067 : StrideIterator::iterator_adaptor_(), stride_(stride)
00068 {
00069 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<RandomAccessIterator>));
00070 }
00071
00075 explicit StrideIterator(RandomAccessIterator p, size_t stride=1)
00076 : StrideIterator::iterator_adaptor_(p), stride_(stride) {}
00077
00078
00082 StrideIterator(const StrideIterator& other)
00083 : StrideIterator::iterator_adaptor_(other.base()), stride_(other.stride())
00084 {}
00085
00094 template<typename I2>
00095 StrideIterator(StrideIterator<I2> other,
00096 typename boost::enable_if_convertible<I2
00097 , RandomAccessIterator>::type* = 0 )
00098 : StrideIterator::iterator_adaptor_(other.base()),
00099 stride_(other.stride()) {}
00100
00104 StrideIterator& operator=(const StrideIterator& rhs)
00105 {
00106 stride_ = rhs.stride();
00107 this->base_reference() = rhs.base();
00108 return *this;
00109 }
00110
00114 inline size_t stride(void) const { return stride_; }
00115
00116 private:
00117
00118 friend class boost::iterator_core_access;
00119
00120 size_t stride_;
00121
00122
00123 typedef typename StrideIterator::iterator_adaptor_::difference_type
00124 difference_t;
00125
00126 void advance(typename super_t::difference_type n)
00127 { this->base_reference() += stride_*n; }
00128
00129 void decrement(void) { this->base_reference()-=stride_; }
00130
00131 template <class OtherIterator>
00132 typename super_t::difference_type
00133 distance_to(const StrideIterator<OtherIterator>& other) const
00134 {
00135
00136 return (other.base() - this->base() )/static_cast<int>(stride_);
00137 }
00138
00139 void increment(void) { this->base_reference()+=stride_; }
00140 };
00141
00142 }}}
00143
00144 #endif