#pragma once #include #include template class IteratorRange { public: IteratorRange(It b, It e) : begin_(b), end_(e), size_(std::distance(b, e)) {} It begin() const { return begin_; } It end() const { return end_; } size_t size() const { return size_; } private: It begin_, end_; size_t size_; }; template class Slicer { public: Slicer(It begin, It end, std::size_t pageSize) { slicedPages = ceil((static_cast(std::distance(begin, end)) / pageSize)); Slice(begin, end, pageSize); } std::size_t size() const { return slicedPages; } auto begin() { return std::begin(pages_); } auto end() { return std::end(pages_); } private: void Slice(It begin, It end, std::size_t pageSize) { It pageIter = begin; for (; pageIter != end;) { std::size_t count{}; begin = pageIter; for (; count < pageSize && pageIter != end;) { count++; pageIter++; } pages_.push_back({begin, pageIter}); } } std::vector> pages_; std::size_t slicedPages = 0; }; template auto Slice(C &c, size_t page_size) { return Slicer(std::begin(c), std::end(c), page_size); } template auto Slice(const C &c, size_t page_size) { return Slicer(c.begin(), c.end(), page_size); } template<> auto Slice(const IteratorRange::iterator> &c, size_t page_size) { return Slicer::iterator>(c.begin(), c.end(), page_size); }