// Example 13-46: A simple 2D matrix class.
#include <cstddef>
#include <valarray>

template<typename T>
class matrix2D {
public:
  matrix2D(std::size_t rows, std::size_t columns) :
    rows_(rows), cols_(columns), data_(rows * columns) {}
  std::size_t rows() const { return rows_; }
  std::size_t cols() const { return cols_; }
  std::valarray<T> row(std::size_t r) const
    { return data_[std::slice(r*cols(),cols(), 1)]; }
  std::valarray<T> col(std::size_t c) const
    { return data_[std::slice(c, rows(), cols())]; }
  std::slice_array<T> row(std::size_t r)
    { return data_[std::slice(r*cols(),cols(), 1)]; }
  std::slice_array<T> col(std::size_t c)
    { return data_[std::slice(c, rows(), cols())]; }
  T& operator()(std::size_t r, std::size_t c)
    { return data_[r*cols()+c]; }
  T operator()(std::size_t r, std::size_t c) const
    { return row(r)[c]; }
  matrix2D<T> transpose() {
    matrix2D<T> result(cols(), rows());
    for (std::size_t i = 0; i < rows(); ++i)
      result.col(i) = static_cast<std::valarray<T> >(row(i));
    return result;
  }
private:
  std::size_t rows_;
  std::size_t cols_;
  std::valarray<T> data_;
};
