first approach including first tests
This commit is contained in:
		@@ -8,4 +8,6 @@
 | 
			
		||||
##       1         2         3         4         5         6         7         8
 | 
			
		||||
## 45678901234567890123456789012345678901234567890123456789012345678901234567890
 | 
			
		||||
 | 
			
		||||
include_HEADERS = matrix.hxx
 | 
			
		||||
 | 
			
		||||
MAINTAINERCLEANFILES = makefile.in
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										299
									
								
								src/matrix.hxx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								src/matrix.hxx
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,299 @@
 | 
			
		||||
/*! @file
 | 
			
		||||
 | 
			
		||||
    @id $Id$
 | 
			
		||||
*/
 | 
			
		||||
//       1         2         3         4         5         6         7         8
 | 
			
		||||
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
 | 
			
		||||
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#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 {
 | 
			
		||||
 | 
			
		||||
    //........................................................const.variables
 | 
			
		||||
  protected:
 | 
			
		||||
    
 | 
			
		||||
    static const size_t SIZE = ROWS*COLUMNS;
 | 
			
		||||
    static const size_t MEM_SIZE = ROWS*COLUMNS*sizeof(T);
 | 
			
		||||
 | 
			
		||||
    //...............................................................typedefs
 | 
			
		||||
  public: 
 | 
			
		||||
 | 
			
		||||
    /// @name Auxiliary Classes
 | 
			
		||||
    ///{
 | 
			
		||||
 | 
			
		||||
    /// Return One Row as Vector, internally used for element access
 | 
			
		||||
    /** Only used to access values:
 | 
			
		||||
 | 
			
		||||
        @code
 | 
			
		||||
        Matrix<int,4,4> m;
 | 
			
		||||
        m[2][2] = 1;
 | 
			
		||||
        @endcode */
 | 
			
		||||
    class RowVector {
 | 
			
		||||
      public:
 | 
			
		||||
        T& operator[](size_t column) {
 | 
			
		||||
          return _v[column];
 | 
			
		||||
        }
 | 
			
		||||
      protected:
 | 
			
		||||
        friend class Matrix;
 | 
			
		||||
        RowVector() = delete; // forbidden
 | 
			
		||||
        RowVector(T c[COLUMNS]): _v(c) {}
 | 
			
		||||
        T *_v;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Same as RowVector, but in a constant environment.
 | 
			
		||||
    class ConstRowVector {
 | 
			
		||||
      public:
 | 
			
		||||
        const T& 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;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    ///}
 | 
			
		||||
 | 
			
		||||
    //................................................................methods
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    /// @name construction
 | 
			
		||||
    ///{
 | 
			
		||||
    
 | 
			
		||||
    Matrix() {
 | 
			
		||||
      LOG;
 | 
			
		||||
      memset(_c, 0, MEM_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    template<typename ...ARGS>
 | 
			
		||||
        Matrix(ARGS...t): _c{std::forward<T>(t)...} {
 | 
			
		||||
      LOG;
 | 
			
		||||
      static_assert(sizeof...(t)==SIZE, "variadic matrix initialisation requires correct array size");
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Matrix(const Matrix& o) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      memcpy(_c, o._c, MEM_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ///}
 | 
			
		||||
 | 
			
		||||
    /// @name operators
 | 
			
		||||
    ///{
 | 
			
		||||
    
 | 
			
		||||
    Matrix& operator=(T oc[ROWS][COLUMNS]) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      memcpy(_c, oc, MEM_SIZE);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Matrix& operator=(const Matrix& o) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      memcpy(_c, o._c, MEM_SIZE);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    Matrix& operator+=(const Matrix& o) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      T *to((T*)(_c)+MEM_SIZE), *from((T*)(o._c)+MEM_SIZE);
 | 
			
		||||
      while (to>(T*)(_c)) *--to += *--from;
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    RowVector operator[](size_t row) {
 | 
			
		||||
      return RowVector(_c[row]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const ConstRowVector operator[](size_t row) const {
 | 
			
		||||
      return ConstRowVector(_c[row]);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ///}
 | 
			
		||||
 | 
			
		||||
    //..............................................................variables
 | 
			
		||||
  protected:
 | 
			
		||||
    
 | 
			
		||||
    T _c[ROWS][COLUMNS];
 | 
			
		||||
    
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template<typename T> class Matrix<T, 0, 0> {
 | 
			
		||||
 | 
			
		||||
    //..............................................................constants
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    const size_t ROWS;
 | 
			
		||||
    const size_t COLUMNS;
 | 
			
		||||
    const size_t SIZE;
 | 
			
		||||
    const size_t MEM_SIZE;
 | 
			
		||||
 | 
			
		||||
    //...............................................................typedefs
 | 
			
		||||
  public: 
 | 
			
		||||
 | 
			
		||||
    /// @name Auxiliary Classes
 | 
			
		||||
    ///{
 | 
			
		||||
 | 
			
		||||
    /// Return One Row as Vector, internally used for element access
 | 
			
		||||
    /** Only used to access values:
 | 
			
		||||
 | 
			
		||||
        @code
 | 
			
		||||
        Matrix<int,4,4> m;
 | 
			
		||||
        m[2][2] = 1;
 | 
			
		||||
        @endcode */
 | 
			
		||||
    class RowVector {
 | 
			
		||||
      public:
 | 
			
		||||
        T& 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) {}
 | 
			
		||||
        const Matrix& _m;
 | 
			
		||||
        T *_v;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /// Same as RowVector, but in a constant environment.
 | 
			
		||||
    class ConstRowVector {
 | 
			
		||||
      public:
 | 
			
		||||
        const T& 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) {}
 | 
			
		||||
        const Matrix& _m;
 | 
			
		||||
        const T *_v;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    ///}
 | 
			
		||||
 | 
			
		||||
    //................................................................methods
 | 
			
		||||
  public:
 | 
			
		||||
 | 
			
		||||
    /// @name construction
 | 
			
		||||
    ///{
 | 
			
		||||
    
 | 
			
		||||
    Matrix(size_t rows, size_t columns):
 | 
			
		||||
        ROWS(rows),
 | 
			
		||||
        COLUMNS(columns),
 | 
			
		||||
        SIZE(rows*columns),
 | 
			
		||||
        MEM_SIZE(rows*columns*sizeof(T)),
 | 
			
		||||
        _c(new T[rows*columns]) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      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);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ///}
 | 
			
		||||
 | 
			
		||||
    /// @name destruction
 | 
			
		||||
    ///{
 | 
			
		||||
 | 
			
		||||
    ~Matrix() {
 | 
			
		||||
      delete[] _c;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ///}
 | 
			
		||||
 | 
			
		||||
    /// @name operators
 | 
			
		||||
    ///{
 | 
			
		||||
    
 | 
			
		||||
    Matrix& operator=(T oc[]) {
 | 
			
		||||
      LOG;
 | 
			
		||||
      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];
 | 
			
		||||
      }
 | 
			
		||||
      memcpy(_c, o._c, MEM_SIZE);
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    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;
 | 
			
		||||
      return *this;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    RowVector operator[](size_t row) {
 | 
			
		||||
      assert(row<ROWS);
 | 
			
		||||
      return RowVector(*this, _c+row*COLUMNS);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const ConstRowVector operator[](size_t row) const {
 | 
			
		||||
      assert(row<ROWS);
 | 
			
		||||
      return ConstRowVector(*this, _c+row*COLUMNS);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ///}
 | 
			
		||||
 | 
			
		||||
    //................................................................methods
 | 
			
		||||
  protected:
 | 
			
		||||
 | 
			
		||||
    void copy_args(T*) {}
 | 
			
		||||
    template<typename ...ARGS>
 | 
			
		||||
        void copy_args(T* to, T t1, ARGS...t) {
 | 
			
		||||
      *to = t1;
 | 
			
		||||
      copy_args(++to, t...);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //..............................................................variables
 | 
			
		||||
  protected:
 | 
			
		||||
    
 | 
			
		||||
    T* _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);
 | 
			
		||||
  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;
 | 
			
		||||
  for (size_t w = 0; w < m.ROWS; ++w) {
 | 
			
		||||
    for (size_t h = 0; h < m.COLUMNS;++h) {
 | 
			
		||||
      s<<m[w][h]<<' ';
 | 
			
		||||
    }
 | 
			
		||||
    s<<'\n';
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user