#pragma once
#include <vector>
template<class It>
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 <typename It>
class Slicer {
public:
explicit Slicer(It begin, It end, int page_size) {
It my_it = begin;
while (my_it < end) {
if (my_it + page_size <= end) {
pages_.push_back(IteratorRange<It>(my_it, my_it + page_size));
} else {
pages_.push_back(IteratorRange<It>(my_it, end));
}
my_it += page_size;
}
}
size_t size() const {
return pages_.size();
}
typename std::vector<IteratorRange<It>>::const_iterator begin() const {
return pages_.begin();
}
typename std::vector<IteratorRange<It>>::const_iterator end() const {
return pages_.end();
}
private:
std::vector<IteratorRange<It>> pages_;
};
template <typename C>
auto Slice(C& c, size_t page_size) {
typedef decltype(c.begin()) type;
Slicer<type> a(c.begin(), c.end(), page_size);
return a;
}
template <typename It>
Slicer<It> Slice(const IteratorRange<It>& c, size_t page_size) {
Slicer<It> a(c.begin(), c.end(), page_size);
return a;
}