/*! @file @id $Id$ */ // 1 2 3 4 5 6 7 8 // 45678901234567890123456789012345678901234567890123456789012345678901234567890 #include #include #include #include #define LOG std::cout<<__PRETTY_FUNCTION__< 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 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 Matrix(ARGS...t): _c{std::forward(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 class Matrix { //..............................................................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 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 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 void copy_args(T* to, T t1, ARGS...t) { *to = t1; copy_args(++to, t...); } //..............................................................variables protected: T* _c; }; template Matrix operator+(const Matrix& m1, const Matrix& m2) { LOG; Matrix res(m1); return res+=m2; } template std::ostream& operator<<(std::ostream& s, const Matrix& m) { LOG; for (size_t w = 0; w < m.ROWS; ++w) { for (size_t h = 0; h < m.COLUMNS;++h) { s<