#ifndef ITER_SLIDING_WINDOW_HPP_ #define ITER_SLIDING_WINDOW_HPP_ #include "internal/iterbase.hpp" #include "internal/iteratoriterator.hpp" #include #include #include namespace iter { namespace impl { template class WindowSlider; } template impl::WindowSlider sliding_window(Container&&, std::size_t); } template class iter::impl::WindowSlider { private: Container container; std::size_t window_size; friend WindowSlider iter::sliding_window(Container&&, std::size_t); WindowSlider(Container&& in_container, std::size_t win_sz) : container(std::forward(in_container)), window_size{win_sz} {} using IndexVector = std::deque>; using DerefVec = IterIterWrapper; public: WindowSlider(WindowSlider&&) = default; class Iterator : public std::iterator { private: iterator_type sub_iter; DerefVec window; public: Iterator(iterator_type&& in_iter, const iterator_type& in_end, std::size_t window_sz) : sub_iter(std::move(in_iter)) { std::size_t i{0}; while (i < window_sz && this->sub_iter != in_end) { this->window.get().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; } bool operator==(const Iterator& other) const { return !(*this != other); } DerefVec& operator*() { return this->window; } DerefVec* operator->() { return this->window; } Iterator& operator++() { ++this->sub_iter; this->window.get().pop_front(); this->window.get().push_back(this->sub_iter); return *this; } Iterator operator++(int) { auto ret = *this; ++*this; return ret; } }; Iterator begin() { return {(this->window_size != 0 ? std::begin(this->container) : std::end(this->container)), std::end(this->container), this->window_size}; } Iterator end() { return {std::end(this->container), std::end(this->container), this->window_size}; } }; template iter::impl::WindowSlider iter::sliding_window( Container&& container, std::size_t window_size) { return {std::forward(container), window_size}; } #endif