<commit_before>#ifndef SLIDING_WINDOW_HPP_
#define SLIDING_WINDOW_HPP_

#include "iterbase.hpp"

#include <vector>
#include <algorithm>
#include <functional>
#include <type_traits>
#include <utility>
#include <iterator>

namespace iter {
    template <typename Container>
    class SlidingWindow;

    template <typename Container>
    SlidingWindow<Container> sliding_window(Container&&, std::size_t);

    template <typename T>
    SlidingWindow<std::initializer_list<T>> sliding_window(
            std::initializer_list<T>, std::size_t);

    template <typename Container>
    class SlidingWindow {
        private:
            Container container;
            std::size_t window_size;

            friend SlidingWindow sliding_window<Container>(
                    Container&&, std::size_t);
            
            template <typename T>
            friend SlidingWindow<std::initializer_list<T>> sliding_window(
                    std::initializer_list<T>, std::size_t);

            SlidingWindow(Container container, std::size_t win_sz)
                : container(std::forward<Container>(container)),
                window_size{win_sz}
            { }

        public:

            class Iterator {
                private:
                    // confusing, but, just makes the type of the vector
                    // returned by operator*()
                    using OpDerefElemType =
                        std::reference_wrapper<
                            typename std::remove_reference<
                                iterator_deref<Container>>::type>;
                    using DerefVec = std::vector<OpDerefElemType>;

                    std::vector<iterator_type<Container>> section;
                    std::size_t section_size = 0;

                public:
                    Iterator(Container& container, std::size_t s)
                        : section_size{s}
                    {
                        auto iter = std::begin(container);
                        auto end = std::end(container);
                        for (std::size_t i = 0;
                                i < section_size && iter != end;
                                ++iter, ++i) {
                            section.push_back(iter);
                        }
                    }

                    // for the end iter
                    Iterator(Container& container)
                        : section{std::end(container)},
                        section_size{0}
                    { }

                    Iterator& operator++() {
                        for (auto&& iter : this->section) {
                            ++iter;
                        }
                        return *this;
                    }

                    bool operator!=(const Iterator& rhs) const {
                       return this->section.back() != rhs.section.back();
                    }

                    DerefVec operator*() {
                        DerefVec vec;
                        for (auto&& iter : this->section) {
                            vec.push_back(*iter);
                        }
                        return vec;
                    }
            };

            Iterator begin() {
                return {container, window_size};
            }

            Iterator end() {
                return {container};
            }
    };

    template <typename Container>
    SlidingWindow<Container> sliding_window(
            Container&& container, std::size_t window_size) {
        return {std::forward<Container>(container), window_size};
    }

    template <typename T>
    SlidingWindow<std::initializer_list<T>> sliding_window(
            std::initializer_list<T> il, std::size_t window_size) {
        return {il, window_size};
    }
}

#endif //SLIDING_WINDOW_HPP_<commit_msg>sliding window lazily consumes iterable<commit_after>#ifndef ITER_SLIDING_WINDOW_HPP_
#define ITER_SLIDING_WINDOW_HPP_

#include "iterbase.hpp"

#include <deque>
#include <utility>
#include <iterator>

namespace iter {
    template <typename Container>
    class SlidingWindow;

    template <typename Container>
    SlidingWindow<Container> sliding_window(Container&&, std::size_t);

    template <typename T>
    SlidingWindow<std::initializer_list<T>> sliding_window(
            std::initializer_list<T>, std::size_t);

    template <typename Container>
    class SlidingWindow {
        private: Container container;
            std::size_t window_size;

            friend SlidingWindow sliding_window<Container>(
                    Container&&, std::size_t);
            
            template <typename T>
            friend SlidingWindow<std::initializer_list<T>> sliding_window(
                    std::initializer_list<T>, std::size_t);

            SlidingWindow(Container container, std::size_t win_sz)
                : container(std::forward<Container>(container)),
                window_size{win_sz}
            { }

        public:

            class Iterator {
                private:
                    // TODO move defs outside and subclass std::iterator
                    using OpDerefElemType = collection_item_type<Container>;
                    using DerefVec = std::deque<OpDerefElemType>;
                    
                    iterator_type<Container> sub_iter;
                    DerefVec window;

                public:
                    Iterator(const iterator_type<Container>& in_iter,
                            const iterator_type<Container>& in_end,
                             std::size_t window_sz)
                        : sub_iter(in_iter)
                    {
                        std::size_t i{0};
                        while (i < window_sz && this->sub_iter != in_end) {
                            this->window.push_back(*this->sub_iter);
                            ++i;
                            if (i != window_sz) ++this->sub_iter;
                        }
                    }

                    bool operator!=(const Iterator& other) const {
                        return this->sub_iter != other.sub_iter;
                    }

                    DerefVec& operator*() {
                        return this->window;
                    }

                    Iterator& operator++() {
                        ++this->sub_iter;
                        this->window.pop_front();
                        this->window.push_back(*this->sub_iter);
                        return *this;
                    }
            };

            Iterator begin() {
                return {std::begin(container),
                    std::end(container),
                    window_size};
            }

            Iterator end() {
                return {std::end(container),
                    std::end(container),
                    window_size};
            }
    };

    template <typename Container>
    SlidingWindow<Container> sliding_window(
            Container&& container, std::size_t window_size) {
        return {std::forward<Container>(container), window_size};
    }

    template <typename T>
    SlidingWindow<std::initializer_list<T>> sliding_window(
            std::initializer_list<T> il, std::size_t window_size) {
        return {il, window_size};
    }
}

#endif
{'fraction_non_alphanumeric': 0.09255948287718332, 'fraction_numerical': 0.0005501306560308073, 'mean_word_length': 1.3595068137573005, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 78, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6568333', 'n_tokens_mistral': 1856, 'n_tokens_neox': 1710, 'n_words': 355}