This is a solution to Advent of Code 2016, Day 8. The tricky part of this problem is that you have to be able to rotate both the rows and columns of a two-dimensional array. Rotating a row is easy using std::rotate, but rotating a column seems much harder.My basic approach was to write a getter function such that get(i) returns the ith element of the (row/column) currently being rotated; and then I wrote a very straightforward rotate by 1 in a loop function in terms of get(i). That implementation is marked // DUMB below. (Although, given this particular problem's range of input, it's not dumb if it works.)But I'd really like to use std::rotate if possible, both for speed (rotate by 1 in a loop is O(byxn), when it should be just O(n)) and for elegance. So I wrote a wrapper that takes the getter function and turns it into an iterator. This is marked // CLEVER below.Does the STL or Boost already provide some way to turn an indexed getter function into a random-access iterator?I turn my array into a getter function and then turn the getter function into an iterator; seems a bit roundabout. Does the STL or Boost already provide a straightforward way to construct a strided iterator on an array?I see that std::iterator is deprecated in C++17. In C++17, would my code Just Work if I stopped inheriting from std::iterator? or what's the best practice for writing iterators these days?#include <assert.h>#include <stdio.h>#include <algorithm>#include <iostream>#include <iterator>#include <regex>#include <string>const int HEIGHT = 6;const int WIDTH = 50;bool grid[HEIGHT][WIDTH];#if 1template<typename Getter>auto make_iterator(const Getter& get, int i)    // CLEVER{    using T = std::remove_reference_t<decltype(get(i))>;    struct It : std::iterator<std::forward_iterator_tag, T> {        const Getter *get_;        int i_;        It(const Getter& g, int i) : get_(&g), i_(i) {}        It& operator++() { ++i_; return *this; }        It operator++(int) { It temp = *this; ++i_; return temp; }        decltype(auto) operator*() const { return (*get_)(i_); }        bool operator==(const It& rhs) const { return i_ == rhs.i_; }        bool operator!=(const It& rhs) const { return i_ != rhs.i_; }    };    return It(get, i);}template<typename Getter>void rotate_right(int by, int n, const Getter& get){    std::rotate(make_iterator(get, 0), make_iterator(get, (n - by) % n), make_iterator(get, n));}#elsetemplate<typename Getter>void rotate_right(int by, int n, const Getter& get){    while (by != 0) {             // DUMB        bool temp = get(n-1);        for (int i = n-1; i >= 0; --i) {            get(i+1) = get(i);        }        get(0) = temp;        --by;    }}#endifvoid process_input(std::string line){    std::smatch m;    if (std::regex_match(line, m, std::regex(rect (.*)x(.*)))) {        int a_wide = std::stoi(m.str(1));        int b_tall = std::stoi(m.str(2));        for (int i=0; i < a_wide; ++i) {            for (int j=0; j < b_tall; ++j) {                grid[j][i] = true;            }        }    } else if (std::regex_match(line, m, std::regex(rotate row y=(.*) by (.*)))) {        int row = std::stoi(m.str(1));        int by = std::stoi(m.str(2)) % WIDTH;        rotate_right(by, WIDTH, [&](int i) -> decltype(auto) { return grid[row][i]; });    } else if (std::regex_match(line, m, std::regex(rotate column x=(.*) by (.*)))) {        int column = std::stoi(m.str(1));        int by = std::stoi(m.str(2)) % HEIGHT;        rotate_right(by, HEIGHT, [&](int i) -> decltype(auto) { return grid[i][column]; });    } else {        assert(false);    }}int main(){    std::string buf;    while (std::getline(std::cin, buf)) {        process_input(buf);    }    for (int i=0; i < HEIGHT; ++i) {        for (int j=0; j < WIDTH; ++j) {            printf(%c, grid[i][j] ? '#' : '.');        }        printf(\n);    }}
Converting a get-by-index function into an iterator for use with STL algorithms
c++;iterator;template meta programming;c++17