more operator, more checks passed
This commit is contained in:
		
							
								
								
									
										191
									
								
								src/matrix.hxx
									
									
									
									
									
								
							
							
						
						
									
										191
									
								
								src/matrix.hxx
									
									
									
									
									
								
							@@ -10,15 +10,15 @@
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <type_traits>
 | 
			
		||||
 | 
			
		||||
#define LOG std::cout<<__PRETTY_FUNCTION__<<std::endl
 | 
			
		||||
 | 
			
		||||
template<typename T, size_t ROWS=0, size_t COLUMNS=0> class Matrix {
 | 
			
		||||
template<typename TYPE, size_t TROWS=0, size_t TCOLUMNS=0> class Matrix {
 | 
			
		||||
 | 
			
		||||
    //........................................................const.variables
 | 
			
		||||
  protected:
 | 
			
		||||
    
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    static const size_t ROWS = TROWS;
 | 
			
		||||
    static const size_t COLUMNS = TCOLUMNS;
 | 
			
		||||
    static const size_t SIZE = ROWS*COLUMNS;
 | 
			
		||||
    static const size_t MEM_SIZE = ROWS*COLUMNS*sizeof(T);
 | 
			
		||||
    static const size_t MEM_SIZE = ROWS*COLUMNS*sizeof(TYPE);
 | 
			
		||||
 | 
			
		||||
    //...............................................................typedefs
 | 
			
		||||
  public: 
 | 
			
		||||
@@ -35,27 +35,27 @@ template<typename T, size_t ROWS=0, size_t COLUMNS=0> class Matrix {
 | 
			
		||||
        @endcode */
 | 
			
		||||
    class RowVector {
 | 
			
		||||
      public:
 | 
			
		||||
        T& operator[](size_t column) {
 | 
			
		||||
        TYPE& operator[](size_t column) {
 | 
			
		||||
          return _v[column];
 | 
			
		||||
        }
 | 
			
		||||
      protected:
 | 
			
		||||
        friend class Matrix;
 | 
			
		||||
        RowVector() = delete; // forbidden
 | 
			
		||||
        RowVector(T c[COLUMNS]): _v(c) {}
 | 
			
		||||
        T *_v;
 | 
			
		||||
        RowVector(TYPE c[COLUMNS]): _v(c) {}
 | 
			
		||||
        TYPE *_v;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Same as RowVector, but in a constant environment.
 | 
			
		||||
    class ConstRowVector {
 | 
			
		||||
      public:
 | 
			
		||||
        const T& operator[](size_t column) const {
 | 
			
		||||
        const TYPE& operator[](size_t column) const {
 | 
			
		||||
          return _v[column];
 | 
			
		||||
        }
 | 
			
		||||
      protected:
 | 
			
		||||
        friend class Matrix;
 | 
			
		||||
        ConstRowVector() = delete; // forbidden
 | 
			
		||||
        ConstRowVector(const T c[COLUMNS]): _v(c) {}
 | 
			
		||||
        const T *_v;
 | 
			
		||||
        ConstRowVector(const TYPE c[COLUMNS]): _v(c) {}
 | 
			
		||||
        const TYPE *_v;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    ///}
 | 
			
		||||
@@ -67,18 +67,15 @@ template<typename T, size_t ROWS=0, size_t COLUMNS=0> class Matrix {
 | 
			
		||||
    ///{
 | 
			
		||||
    
 | 
			
		||||
    Matrix() {
 | 
			
		||||
      LOG;
 | 
			
		||||
      memset(_c, 0, MEM_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template<typename ...ARGS>
 | 
			
		||||
        Matrix(ARGS...t): _c{std::forward<T>(t)...} {
 | 
			
		||||
      LOG;
 | 
			
		||||
        Matrix(ARGS...t): _c{std::forward<TYPE>(t)...} {
 | 
			
		||||
      static_assert(sizeof...(t)==SIZE, "variadic matrix initialisation requires correct array size");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Matrix(const Matrix& o) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      memcpy(_c, o._c, MEM_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -87,30 +84,76 @@ template<typename T, size_t ROWS=0, size_t COLUMNS=0> class Matrix {
 | 
			
		||||
    /// @name operators
 | 
			
		||||
    ///{
 | 
			
		||||
    
 | 
			
		||||
    Matrix& operator=(T oc[ROWS][COLUMNS]) {
 | 
			
		||||
      LOG;
 | 
			
		||||
    Matrix& operator=(TYPE oc[ROWS][COLUMNS]) {
 | 
			
		||||
      memcpy(_c, oc, MEM_SIZE);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Matrix& operator=(const Matrix& o) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      memcpy(_c, o._c, MEM_SIZE);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    bool operator==(const Matrix& o) const {
 | 
			
		||||
      TYPE *to((TYPE*)(_c)+SIZE), *from((TYPE*)(o._c)+SIZE);
 | 
			
		||||
      while (to>(TYPE*)(_c)) if (*--to != *--from) return false;
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator!=(const Matrix& o) const {
 | 
			
		||||
      return !operator==(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Matrix<TYPE, COLUMNS, ROWS> T() const {
 | 
			
		||||
      Matrix<TYPE, COLUMNS, ROWS> res;
 | 
			
		||||
      for (size_t row(0); row<ROWS; ++row)
 | 
			
		||||
        for (size_t column(0); column<COLUMNS; ++column)
 | 
			
		||||
          res(column, row) = operator()(row, column);
 | 
			
		||||
      return res;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Matrix operator-() const {
 | 
			
		||||
      Matrix res;
 | 
			
		||||
      for (TYPE *to((TYPE*)(res._c)+SIZE); to>(TYPE*)(_c); --to) *to = -*to;
 | 
			
		||||
      return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Matrix& operator+=(const Matrix& o) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      T *to((T*)(_c)+MEM_SIZE), *from((T*)(o._c)+MEM_SIZE);
 | 
			
		||||
      while (to>(T*)(_c)) *--to += *--from;
 | 
			
		||||
      TYPE *to((TYPE*)(_c)+SIZE), *from((TYPE*)(o._c)+SIZE);
 | 
			
		||||
      while (to>(TYPE*)(_c)) *--to += *--from;
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Matrix& operator-=(const Matrix& o) {
 | 
			
		||||
      TYPE *to((TYPE*)(_c)+SIZE), *from((TYPE*)(o._c)+SIZE);
 | 
			
		||||
      while (to>(TYPE*)(_c)) *--to -= *--from;
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ///}
 | 
			
		||||
 | 
			
		||||
    /// @name element access
 | 
			
		||||
    ///{
 | 
			
		||||
 | 
			
		||||
    TYPE& operator()(size_t row, size_t column) {
 | 
			
		||||
      assert(row<ROWS);
 | 
			
		||||
      assert(column<COLUMNS);
 | 
			
		||||
      return _c[row][column];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const TYPE& operator()(size_t row, size_t column) const {
 | 
			
		||||
      assert(row<ROWS);
 | 
			
		||||
      assert(column<COLUMNS);
 | 
			
		||||
      return _c[row][column];
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    RowVector operator[](size_t row) {
 | 
			
		||||
      assert(row<ROWS);
 | 
			
		||||
      return RowVector(_c[row]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const ConstRowVector operator[](size_t row) const {
 | 
			
		||||
      assert(row<ROWS);
 | 
			
		||||
      return ConstRowVector(_c[row]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
@@ -119,11 +162,11 @@ template<typename T, size_t ROWS=0, size_t COLUMNS=0> class Matrix {
 | 
			
		||||
    //..............................................................variables
 | 
			
		||||
  protected:
 | 
			
		||||
    
 | 
			
		||||
    T _c[ROWS][COLUMNS];
 | 
			
		||||
    TYPE _c[ROWS][COLUMNS];
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T> class Matrix<T, 0, 0> {
 | 
			
		||||
template<typename TYPE> class Matrix<TYPE, 0, 0> {
 | 
			
		||||
 | 
			
		||||
    //..............................................................constants
 | 
			
		||||
  public:
 | 
			
		||||
@@ -148,31 +191,31 @@ template<typename T> class Matrix<T, 0, 0> {
 | 
			
		||||
        @endcode */
 | 
			
		||||
    class RowVector {
 | 
			
		||||
      public:
 | 
			
		||||
        T& operator[](size_t column) {
 | 
			
		||||
        TYPE& operator[](size_t column) {
 | 
			
		||||
          assert(column<_m.COLUMNS);
 | 
			
		||||
          return _v[column];
 | 
			
		||||
        }
 | 
			
		||||
      protected:
 | 
			
		||||
        friend class Matrix;
 | 
			
		||||
        RowVector() = delete; // forbidden
 | 
			
		||||
        RowVector(const Matrix& m, T c[]): _m(m), _v(c) {}
 | 
			
		||||
        RowVector(const Matrix& m, TYPE c[]): _m(m), _v(c) {}
 | 
			
		||||
        const Matrix& _m;
 | 
			
		||||
        T *_v;
 | 
			
		||||
        TYPE *_v;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Same as RowVector, but in a constant environment.
 | 
			
		||||
    class ConstRowVector {
 | 
			
		||||
      public:
 | 
			
		||||
        const T& operator[](size_t column) const {
 | 
			
		||||
        const TYPE& operator[](size_t column) const {
 | 
			
		||||
          assert(column<_m.COLUMNS);
 | 
			
		||||
          return _v[column];
 | 
			
		||||
        }
 | 
			
		||||
      protected:
 | 
			
		||||
        friend class Matrix;
 | 
			
		||||
        ConstRowVector() = delete; // forbidden
 | 
			
		||||
        ConstRowVector(const Matrix& m, const T c[]): _m(m), _v(c) {}
 | 
			
		||||
        ConstRowVector(const Matrix& m, const TYPE c[]): _m(m), _v(c) {}
 | 
			
		||||
        const Matrix& _m;
 | 
			
		||||
        const T *_v;
 | 
			
		||||
        const TYPE *_v;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    ///}
 | 
			
		||||
@@ -187,22 +230,19 @@ template<typename T> class Matrix<T, 0, 0> {
 | 
			
		||||
        ROWS(rows),
 | 
			
		||||
        COLUMNS(columns),
 | 
			
		||||
        SIZE(rows*columns),
 | 
			
		||||
        MEM_SIZE(rows*columns*sizeof(T)),
 | 
			
		||||
        _c(new T[rows*columns]) {
 | 
			
		||||
      LOG;
 | 
			
		||||
        MEM_SIZE(rows*columns*sizeof(TYPE)),
 | 
			
		||||
        _c(new TYPE[rows*columns]) {
 | 
			
		||||
      memset(_c, 0, MEM_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template<typename ...ARGS>
 | 
			
		||||
        Matrix(size_t rows, size_t columns, ARGS...t):
 | 
			
		||||
            Matrix(rows, columns) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      assert(sizeof...(t)==SIZE);
 | 
			
		||||
      copy_args(_c, t...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Matrix(const Matrix& o): Matrix(o.ROWS, o.COLUMNS) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      memcpy(_c, o._c, MEM_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -220,36 +260,83 @@ template<typename T> class Matrix<T, 0, 0> {
 | 
			
		||||
    /// @name operators
 | 
			
		||||
    ///{
 | 
			
		||||
    
 | 
			
		||||
    Matrix& operator=(T oc[]) {
 | 
			
		||||
      LOG;
 | 
			
		||||
    Matrix& operator=(TYPE oc[]) {
 | 
			
		||||
      assert(sizeof(oc)==MEM_SIZE);
 | 
			
		||||
      memcpy(_c, oc, MEM_SIZE);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Matrix& operator=(const Matrix& o) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      if (o.ROWS!=ROWS&&o.COLUMNS!=COLUMNS) {
 | 
			
		||||
        delete[] _c;
 | 
			
		||||
        ROWS = o.ROWS;
 | 
			
		||||
        COLUMNS = o.COLUMNS;
 | 
			
		||||
        SIZE = o.SIZE;
 | 
			
		||||
        MEM_SIZE = o.MEM_SIZE;
 | 
			
		||||
        _c = new T[SIZE];
 | 
			
		||||
        _c = new TYPE[SIZE];
 | 
			
		||||
      }
 | 
			
		||||
      memcpy(_c, o._c, MEM_SIZE);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    bool operator==(const Matrix& o) const {
 | 
			
		||||
      if (o.ROWS!=ROWS||o.COLUMNS!=COLUMNS) return false;
 | 
			
		||||
      TYPE *to((TYPE*)(_c)+SIZE), *from((TYPE*)(o._c)+SIZE);
 | 
			
		||||
      while (to>(TYPE*)(_c)) if (*--to != *--from) return false;
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool operator!=(const Matrix& o) const {
 | 
			
		||||
      return !operator==(o);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Matrix T() const {
 | 
			
		||||
      Matrix res(COLUMNS, ROWS);
 | 
			
		||||
      for (size_t row(0); row<ROWS; ++row)
 | 
			
		||||
        for (size_t column(0); column<COLUMNS; ++column)
 | 
			
		||||
          res(column, row) = operator()(row, column);
 | 
			
		||||
      return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Matrix operator-() const {
 | 
			
		||||
      Matrix res(COLUMNS, ROWS);
 | 
			
		||||
      for (TYPE *to((TYPE*)(res._c)+SIZE); to>(TYPE*)(_c); --to) *to = -*to;
 | 
			
		||||
      return res;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Matrix& operator+=(const Matrix& o) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      assert(o.ROWS==ROWS);
 | 
			
		||||
      assert(o.COLUMNS==COLUMNS);
 | 
			
		||||
      T *to((T*)(_c)+MEM_SIZE), *from((T*)(o._c)+MEM_SIZE);
 | 
			
		||||
      while (to>(T*)(_c)) *--to += *--from;
 | 
			
		||||
      TYPE *to((TYPE*)(_c)+SIZE), *from((TYPE*)(o._c)+SIZE);
 | 
			
		||||
      while (to>(TYPE*)(_c)) *--to += *--from;
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Matrix& operator-=(const Matrix& o) {
 | 
			
		||||
      assert(o.ROWS==ROWS);
 | 
			
		||||
      assert(o.COLUMNS==COLUMNS);
 | 
			
		||||
      TYPE *to((TYPE*)(_c)+SIZE), *from((TYPE*)(o._c)+SIZE);
 | 
			
		||||
      while (to>(TYPE*)(_c)) *--to -= *--from;
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ///}
 | 
			
		||||
 | 
			
		||||
    /// @name element access
 | 
			
		||||
    ///{
 | 
			
		||||
    
 | 
			
		||||
    TYPE& operator()(size_t row, size_t column) {
 | 
			
		||||
      assert(row<ROWS);
 | 
			
		||||
      assert(column<COLUMNS);
 | 
			
		||||
      return *(_c+row*COLUMNS+column);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const TYPE& operator()(size_t row, size_t column) const {
 | 
			
		||||
      assert(row<ROWS);
 | 
			
		||||
      assert(column<COLUMNS);
 | 
			
		||||
      return *(_c+row*COLUMNS+column);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    RowVector operator[](size_t row) {
 | 
			
		||||
      assert(row<ROWS);
 | 
			
		||||
      return RowVector(*this, _c+row*COLUMNS);
 | 
			
		||||
@@ -265,9 +352,9 @@ template<typename T> class Matrix<T, 0, 0> {
 | 
			
		||||
    //................................................................methods
 | 
			
		||||
  protected:
 | 
			
		||||
 | 
			
		||||
    void copy_args(T*) {}
 | 
			
		||||
    void copy_args(TYPE*) {}
 | 
			
		||||
    template<typename ...ARGS>
 | 
			
		||||
        void copy_args(T* to, T t1, ARGS...t) {
 | 
			
		||||
        void copy_args(TYPE* to, TYPE t1, ARGS...t) {
 | 
			
		||||
      *to = t1;
 | 
			
		||||
      copy_args(++to, t...);
 | 
			
		||||
    }
 | 
			
		||||
@@ -275,20 +362,18 @@ template<typename T> class Matrix<T, 0, 0> {
 | 
			
		||||
    //..............................................................variables
 | 
			
		||||
  protected:
 | 
			
		||||
    
 | 
			
		||||
    T* _c;
 | 
			
		||||
    TYPE* _c;
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T, size_t ROWS, size_t COLUMNS>
 | 
			
		||||
    Matrix<T, ROWS, COLUMNS> operator+(const Matrix<T, ROWS, COLUMNS>& m1, const Matrix<T, ROWS, COLUMNS>& m2) {
 | 
			
		||||
  LOG;
 | 
			
		||||
  Matrix<T, ROWS, COLUMNS> res(m1);
 | 
			
		||||
template<typename TYPE, size_t ROWS, size_t COLUMNS>
 | 
			
		||||
    Matrix<TYPE, ROWS, COLUMNS> operator+(const Matrix<TYPE, ROWS, COLUMNS>& m1, const Matrix<TYPE, ROWS, COLUMNS>& m2) {
 | 
			
		||||
  Matrix<TYPE, ROWS, COLUMNS> res(m1);
 | 
			
		||||
  return res+=m2;
 | 
			
		||||
}
 | 
			
		||||
                     
 | 
			
		||||
template<typename T, size_t ROWS, size_t COLUMNS>
 | 
			
		||||
    std::ostream& operator<<(std::ostream& s, const Matrix<T, ROWS, COLUMNS>& m) {
 | 
			
		||||
  LOG;
 | 
			
		||||
template<typename TYPE, size_t ROWS, size_t COLUMNS>
 | 
			
		||||
    std::ostream& operator<<(std::ostream& s, const Matrix<TYPE, ROWS, COLUMNS>& m) {
 | 
			
		||||
  for (size_t w = 0; w < m.ROWS; ++w) {
 | 
			
		||||
    for (size_t h = 0; h < m.COLUMNS;++h) {
 | 
			
		||||
      s<<m[w][h]<<' ';
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user