#include #include #include #include #include #include template class Block_Container; template class Block_Iterator { using iterator = typename Container::const_iterator; public: bool operator==(Block_Iterator const& other) const { return block_begin == other.block_begin; } bool operator!=(Block_Iterator const& other) const { return !(*this == other); } std::vector operator*() { return { block_begin, block_end }; } Block_Iterator& operator++() { block_begin = block_end; block_end = next_block(block_end); return *this; } Block_Iterator operator++(int) { Block_Iterator tmp { *this }; ++(*this); return tmp; } private: Block_Iterator(iterator begin, iterator end) : block_begin { begin }, block_end { begin }, container_end { end } { block_end = next_block(block_end); } iterator next_block(iterator current) const { for (std::size_t i { 0 }; i < block_size; ++i) { if (current == container_end) { break; } ++current; } return current; } friend class Block_Container; iterator block_begin; iterator block_end; iterator container_end; }; template class Block_Container { public: Block_Container(Container const& container) : container { container } { } Block_Iterator begin() { return { std::begin(container), std::end(container) }; } Block_Iterator end() { return { std::end(container), std::end(container) }; } private: Container const& container; }; template Block_Container make_blocks(Container const& container) { return { container }; } int main() { { std::set v { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 }; Block_Container, 4> blocks { v }; auto it { blocks.begin() }; assert(( *it++ == std::vector{ 1, 2, 3, 4 } )); assert(( *it++ == std::vector{ 5, 6, 7, 8 } )); assert(( *it++ == std::vector{ 9, 10, 11, 12 } )); // there aren't enough elements to split this evenly so the // "rest" is placed in the final block. assert(( *it++ == std::vector{ 13 } )); assert( it == blocks.end() ); } { std::vector fruits { "Mango", "Pineapple", "Papaya", "Blueberries", "Blackberries", "Raspberries", "Pear", "Plum", "Peach", "Kiwi", "Passion fruit", "Lychee" }; std::size_t offset { 0 }; for (auto block : make_blocks<3>(fruits)) { for (std::size_t i { 0 }; i < block.size(); ++i) { assert( block[i] == fruits[offset + i] ); } offset += block.size(); } } }