#include <iostream> #include <utility> #include <vector> #include <array> #include <iterator> namespace details { template<unsigned...>struct indexes { using type=indexes; }; template<unsigned max, unsigned... is>struct make_indexes:make_indexes<max-1, max-1, is...>{}; template<unsigned... is>struct make_indexes<0,is...>:indexes<is...>{}; template<unsigned max>using make_indexes_t=typename make_indexes<max>::type; template<bool b, class T=void> using enable_if_t=typename std::enable_if<b,T>::type; struct list_tag {}; struct from_iterator_tag {}; template<unsigned N, class Iterator> struct iterator_array { private: std::array<Iterator,N> raw; size_t index = 0; static Iterator to_elem(Iterator& it, Iterator end, bool advance=true) { if (it == end) return end; if (advance) return ++it; return it; } template< unsigned...Is> iterator_array( indexes<Is...>, from_iterator_tag, Iterator& it, Iterator end ): raw( {to_elem(it, end, false), (void(Is), to_elem(it,end))...} ) {} public: Iterator begin() const { return raw[index]; } Iterator end() const { return std::next(raw[(index+N-1)%N]); } void push_back( Iterator it ) { raw[index] = it; index = (index+1)%N; } iterator_array( from_iterator_tag, Iterator& it, Iterator end ):iterator_array( make_indexes<N-1>{}, from_iterator_tag{}, it, end ) {} iterator_array( iterator_array const& o )=default; iterator_array() = default; // invalid! iterator_array& operator=( iterator_array const& o )=delete; typedef decltype(*std::declval<Iterator>()) reference_type; reference_type operator[](std::size_t i)const{return *(raw[ (i+index)%N ]);} }; struct sentinal_tag {}; template<class I>using value_type_t=typename std::iterator_traits<I>::value_type; template<class I, unsigned N> class slide_iterator:public std::iterator< std::forward_iterator_tag, iterator_array<N,I>, iterator_array<N,I>*, iterator_array<N,I> const& > { I current; mutable bool bread = false; typedef iterator_array<N,I> value_type; mutable value_type data; void ensure_read() const { if (!bread) { data.push_back(current); } bread = true; } public: slide_iterator& operator++() { ensure_read(); ++current; bread=false; return *this; } slide_iterator operator++(int) { slide_iterator retval=*this; ++*this; return retval; } value_type const& operator*() const { ensure_read(); return data; } bool operator==(slide_iterator const& o){return current==o.current;} bool operator!=(slide_iterator const& o){return current!=o.current;} bool operator<(slide_iterator const& o){return current<o.current;} bool operator>(slide_iterator const& o){return current>o.current;} bool operator<=(slide_iterator const& o){return current<=o.current;} bool operator>=(slide_iterator const& o){return current>=o.current;} explicit slide_iterator( I start, I end ):current(start), bread(true), data(from_iterator_tag{}, current, end) {} explicit slide_iterator( sentinal_tag, I end ):current(end) {} }; } template<class Iterator, unsigned N> struct slide_range_t { using iterator=details::slide_iterator<Iterator, N>; iterator b; iterator e; slide_range_t( Iterator start, Iterator end ): b( start, end ), e( details::sentinal_tag{}, end ) {} slide_range_t( slide_range_t const& o )=default; slide_range_t() = delete; iterator begin() const { return b; } iterator end() const { return e; } }; template<unsigned N, class Iterator> slide_range_t< Iterator, N > slide_range( Iterator b, Iterator e ) { return {b,e}; } int main() { std::vector<int> foo(33); for (int i = 0; i < foo.size(); ++i) foo[i]=i; for( auto&& r:slide_range<3>(foo.begin(), foo.end()) ) { for (int x:r) { std::cout << x << ","; } std::cout << "\n"; } }
Standard input is empty
0,1,2, 1,2,3, 2,3,4, 3,4,5, 4,5,6, 5,6,7, 6,7,8, 7,8,9, 8,9,10, 9,10,11, 10,11,12, 11,12,13, 12,13,14, 13,14,15, 14,15,16, 15,16,17, 16,17,18, 17,18,19, 18,19,20, 19,20,21, 20,21,22, 21,22,23, 22,23,24, 23,24,25, 24,25,26, 25,26,27, 26,27,28, 27,28,29, 28,29,30, 29,30,31, 30,31,32,