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 b, It e, int page_size) : size_(ceil(std::distance(b, e) / static_cast(page_size))) { auto beg = b; for (; b != e; ++b) { if (std::distance(beg, b)+1 == page_size) { pages_.push_back(IteratorRange(beg, ++b)); beg = b; } if (std::distance(beg, e) < page_size) { if (std::distance(beg, e) > 0) { pages_.push_back(IteratorRange(beg, e)); } break; } } } auto begin() const { return pages_.begin(); } auto end() const { return pages_.end(); } size_t size() const { return size_; } private: std::vector> pages_; size_t size_; }; template auto Slice(C &c, size_t page_size) { return Slicer(c.begin(), c.end(), 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); }