#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";
    }
}