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 "iterator_traits.h"
00027
00028 #include <boost/concept_check.hpp>
00029 #include <boost/iterator/iterator_adaptor.hpp>
00030
00031 namespace theplu {
00032 namespace yat {
00033 namespace utility {
00034
00043 template<typename RandomAccessIterator>
00044 class StrideIterator
00045 : public boost::iterator_adaptor<StrideIterator<RandomAccessIterator>
00046 , RandomAccessIterator>
00047 {
00048 typedef boost::iterator_adaptor<StrideIterator<RandomAccessIterator>,
00049 RandomAccessIterator> super_t;
00050
00051 public:
00053 typedef RandomAccessIterator iterator_type;
00054
00060 explicit StrideIterator(size_t stride=1)
00061 : StrideIterator::iterator_adaptor_(), stride_(stride)
00062 {
00063 BOOST_CONCEPT_ASSERT((boost::RandomAccessIterator<RandomAccessIterator>));
00064 }
00065
00069 explicit StrideIterator(RandomAccessIterator p, size_t stride=1)
00070 : StrideIterator::iterator_adaptor_(p), stride_(stride) {}
00071
00072
00076 StrideIterator(const StrideIterator& other)
00077 : StrideIterator::iterator_adaptor_(other.base()), stride_(other.stride())
00078 {}
00079
00088 template<typename I2>
00089 StrideIterator(StrideIterator<I2> other,
00090 typename boost::enable_if_convertible<I2
00091 , RandomAccessIterator>::type* = 0 )
00092 : StrideIterator::iterator_adaptor_(other.base()),
00093 stride_(other.stride()) {}
00094
00098 StrideIterator& operator=(const StrideIterator& rhs)
00099 {
00100 stride_ = rhs.stride();
00101 this->base_reference() = rhs.base();
00102 return *this;
00103 }
00104
00108 inline size_t stride(void) const { return stride_; }
00109
00110 private:
00111
00112 friend class boost::iterator_core_access;
00113
00114 size_t stride_;
00115
00116
00117 typedef typename StrideIterator::iterator_adaptor_::difference_type
00118 difference_t;
00119
00120 void advance(typename super_t::difference_type n)
00121 { this->base_reference() += stride_*n; }
00122
00123 void decrement(void) { this->base_reference()-=stride_; }
00124
00125 template <class OtherIterator>
00126 typename super_t::difference_type
00127 distance_to(const StrideIterator<OtherIterator>& other) const
00128 {
00129
00130 return (other.base() - this->base() )/static_cast<int>(stride_);
00131 }
00132
00133 void increment(void) { this->base_reference()+=stride_; }
00134 };
00135
00136 }}}
00137
00138 #endif