Skip to content

Instantly share code, notes, and snippets.

@rep-movsd
Created May 17, 2016 20:09
Show Gist options
  • Save rep-movsd/2336b60345408ec6dde389a945c87666 to your computer and use it in GitHub Desktop.
Save rep-movsd/2336b60345408ec6dde389a945c87666 to your computer and use it in GitHub Desktop.
Basic 2D iterator
#include <bits/stdc++.h>
#define mp make_pair
#define vstr vector<string>
#define pb push_back
#define all(x) begin(x), end(x)
#define sz(x) int(x.size())
#define P(X) cout << X << "\t"
#define NL cout << endl
#define FOR(I,N) for(int I = 0; I < N; ++I)
using namespace std;
typedef pair<int, int> Coord;
typedef pair<int, int> Incr;
static constexpr Incr UP = mp(-1, 0), DN = mp(1, 0), LT = mp(0, -1), RT = mp(0, 1);
static constexpr Incr NE = mp(-1, 1), NW = mp(-1, -1), SE = mp(1, 1), SW = mp(1, -1);
template<typename T> struct Iter2d
{
#define x second
#define y first
vector<vector<T>> *pv;
Incr incr;
Coord pos;
Iter2d():pv(NULL){}
Iter2d(vector<vector<T>> &v1, const Coord &pos1, const Incr &incr1 = RT):pv(&v1), incr(incr1), pos(pos1) {}
Iter2d& operator=(const Iter2d& o) {pv = o.pv; incr = o.incr; pos = o.pos; return *this;}
T &operator*() {return (*pv)[pos.y][pos.x];}
Iter2d operator()(Incr i) const {return Iter2d(*pv, pos, i);}
operator bool() const {return pos.y >= 0 && pos.x >= 0 && pos.y < w() && pos.x < h();}
bool operator<(const Iter2d &o) const {return (!incr.y || (pos.y < o.pos.y)) && (!incr.x || (pos.x < o.pos.x));}
bool operator ==(const Iter2d &o) const {return o.pos.y == pos.y && o.pos.x == pos.x;}
bool operator !=(const Iter2d &o) const {return !(o == *this);}
Iter2d &operator++()
{
pos.y += incr.y; pos.y = min(pos.y, h()); pos.y = max(pos.y, -1);
pos.x += incr.x; pos.x = min(pos.x, w()); pos.x = max(pos.x, -1);
return *this;
}
Iter2d next() { Iter2d it = *this; return ++it;}
int h() const { return pv->size(); }
int w() const { return ((*pv)[0]).size(); }
int distance(const Iter2d &o) const
{
int count = 0;
Iter2d ite = *this;
while(ite != o) {++ite; ++count;}
return count;
}
Iter2d end() const
{
Iter2d ite = *this;
while(ite.pos.y >=0 && ite.pos.y < h() && ite.pos.x >= 0 && ite.pos.x < w()) ++ite;
return ite;
}
typedef typename vector<T>::difference_type difference_type;
typedef typename vector<T>::value_type value_type;
typedef typename vector<T>::reference reference;
typedef typename vector<T>::pointer pointer;
typedef typename vector<T>::iterator::iterator_category iterator_category;
#undef x
#undef y
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment