// Copyright David Abrahams 2008. Distributed under the Boost // Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #define _GLIBCXX_DEBUG 1 #include "boost/iterator/iterator_adaptor.hpp" #include "boost/iterator/counting_iterator.hpp" //#include #include #include #include #include template struct strided_iterator : boost::iterator_adaptor< strided_iterator, RandomAccessIterator > { strided_iterator() {} explicit strided_iterator( RandomAccessIterator p, RandomAccessIterator finish ) : strided_iterator::iterator_adaptor_(p), finish(finish) { } private: friend class boost::iterator_core_access; void increment() { if (finish - this->base() >= N) this->base_reference() += N; else this->base_reference() = finish; } void decrement() { this->base_reference() -= N; } typename strided_iterator::difference_type distance_to(strided_iterator const& rhs) const { return (rhs.base() - this->base() + N - 1) / N; } void advance(typename strided_iterator::difference_type x) { if (x > 0) { if (finish - this->base() >= N*x) this->base_reference() += N*x; else this->base_reference() = finish; } else { this->base_reference() -= x*N; } } RandomAccessIterator finish; }; template strided_iterator make_strided_iterator(I pos, I finish) { return strided_iterator(pos, finish); } int main() { boost::counting_iterator start(0); boost::counting_iterator finish(13*7); int total = std::accumulate( make_strided_iterator<5>(start, finish), make_strided_iterator<5>(finish, finish), 0); int t2 = 0; for (int i = 0; i < 13*7; i+=5) t2 += i; assert(total == t2); std::copy( make_strided_iterator<5>(start, finish), make_strided_iterator<5>(finish, finish), std::ostream_iterator(std::cout, " ")); }