#ifndef ARRAY2D_H_ #define ARRAY2D_H_ #include #include #include #include #include template class Array2D { public: typedef typename std::vector::reference reference; typedef typename std::vector::const_reference const_reference; typedef typename std::vector::iterator iterator; typedef typename std::vector::const_iterator const_iterator; Array2D() : width_(0), height_(0) {} Array2D(int w, int h, const T& d = T()) : width_(w), height_(h), data_(w*h, d) {} Array2D(const Array2D& rhs) : width_(rhs.width_), height_(rhs.height_), data_(rhs.data_) {} bool empty() const { return data_.empty(); } void resize(int w, int h, const T& d = T()) { data_.resize(w * h, d); width_ = w; height_ = h; } const Array2D& operator=(const Array2D& rhs) { data_ = rhs.data_; width_ = rhs.width_; height_ = rhs.height_; return *this; } void fill(const T& v) { data_.assign(data_.size(), v); } int width() const { return width_; } int height() const { return height_; } reference operator()(int i, int j) { return data_[offset(i, j)]; } void clear() { data_.clear(); width_=0; height_=0; } const_reference operator()(int i, int j) const { return data_[offset(i, j)]; } iterator begin_col(int j) { return data_.begin() + offset(0,j); } const_iterator begin_col(int j) const { return data_.begin() + offset(0,j); } iterator end_col(int j) { return data_.begin() + offset(0,j) + width_; } const_iterator end_col(int j) const { return data_.begin() + offset(0,j) + width_; } iterator end() { return data_.end(); } const_iterator end() const { return data_.end(); } const Array2D& operator*=(const T& x) { std::transform(data_.begin(), data_.end(), data_.begin(), std::bind2nd(std::multiplies(), x)); } const Array2D& operator/=(const T& x) { std::transform(data_.begin(), data_.end(), data_.begin(), std::bind2nd(std::divides(), x)); } const Array2D& operator+=(const Array2D& m) { std::transform(m.data_.begin(), m.data_.end(), data_.begin(), data_.begin(), std::plus()); } const Array2D& operator-=(const Array2D& m) { std::transform(m.data_.begin(), m.data_.end(), data_.begin(), data_.begin(), std::minus()); } private: inline int offset(int i, int j) const { assert(i data_; }; template Array2D operator*(const Array2D& l, const T& scalar) { Array2D res(l); res *= scalar; return res; } template Array2D operator*(const T& scalar, const Array2D& l) { Array2D res(l); res *= scalar; return res; } template Array2D operator/(const Array2D& l, const T& scalar) { Array2D res(l); res /= scalar; return res; } template Array2D operator+(const Array2D& l, const Array2D& r) { Array2D res(l); res += r; return res; } template Array2D operator-(const Array2D& l, const Array2D& r) { Array2D res(l); res -= r; return res; } template inline std::ostream& operator<<(std::ostream& os, const Array2D& m) { for (int i=0; i& m) { os << ' '; for (int j=0; j >& m) { os << ' '; for (int j=0; j& ar = m(i,j); for (unsigned k=0; k