#pragma once #include template class IteratorRange { public: IteratorRange(It b, It e) : begin_(b), end_(e), size_(std::distance(b, e)) {} [[nodiscard]] It begin() const { return begin_; } [[nodiscard]] It end() const { return end_; } [[nodiscard]] std::size_t size() const { return size_; } private: It begin_, end_; std::size_t size_; }; template class Slicer { public: Slicer(It b, It e, std::size_t page_size) { std::size_t i = 0; It begin = b, end = b; for (; end != e;) { ++i; ++end; if (i == page_size) { pages_.push_back(IteratorRange(begin, end)); i = 0; begin = end; continue; } } if (i > 0) { pages_.push_back(IteratorRange(begin, end)); } } [[nodiscard]] auto begin() const { return pages_.begin(); } [[nodiscard]] auto end() const { return pages_.end(); } std::size_t size() { return pages_.size(); } private: // It begin_, end_; std::vector> pages_; }; template auto Slice(C &c, std::size_t page_size) { return Slicer(c.begin(), c.end(), page_size); } template auto Slice(const C &c, std::size_t page_size) { return Slicer(c.begin(), c.end(), page_size); } template<> auto Slice(const IteratorRange::iterator> &c, std::size_t page_size) { return Slicer::iterator>(c.begin(), c.end(), page_size); }