From 8f37bef3e9da3d2a55c0a96e8d8f9ccb752419b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Mon, 8 Aug 2016 20:03:54 +0000 Subject: [PATCH] more operator, more checks passed --- src/matrix.hxx | 191 +++++++++++++++++++++++++++++++++++-------------- test/basic.cxx | 84 +++++++++++++++++++++- 2 files changed, 220 insertions(+), 55 deletions(-) diff --git a/src/matrix.hxx b/src/matrix.hxx index c6c6236..26e4ee4 100644 --- a/src/matrix.hxx +++ b/src/matrix.hxx @@ -10,15 +10,15 @@ #include #include -#define LOG std::cout<<__PRETTY_FUNCTION__< class Matrix { +template 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 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 class Matrix { ///{ Matrix() { - LOG; memset(_c, 0, MEM_SIZE); } template - Matrix(ARGS...t): _c{std::forward(t)...} { - LOG; + Matrix(ARGS...t): _c{std::forward(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 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 T() const { + Matrix res; + for (size_t row(0); row(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 class Matrix { //..............................................................variables protected: - T _c[ROWS][COLUMNS]; + TYPE _c[ROWS][COLUMNS]; }; -template class Matrix { +template class Matrix { //..............................................................constants public: @@ -148,31 +191,31 @@ template class Matrix { @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 class Matrix { 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 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 class Matrix { /// @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(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 class Matrix { //................................................................methods protected: - void copy_args(T*) {} + void copy_args(TYPE*) {} template - 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 class Matrix { //..............................................................variables protected: - T* _c; + TYPE* _c; }; -template - Matrix operator+(const Matrix& m1, const Matrix& m2) { - LOG; - Matrix res(m1); +template + Matrix operator+(const Matrix& m1, const Matrix& m2) { + Matrix res(m1); return res+=m2; } -template - std::ostream& operator<<(std::ostream& s, const Matrix& m) { - LOG; +template + std::ostream& operator<<(std::ostream& s, const Matrix& m) { for (size_t w = 0; w < m.ROWS; ++w) { for (size_t h = 0; h < m.COLUMNS;++h) { s< - void initFromDefault() { + void initFromDefault() { Matrix m; CPPUNIT_ASSERT_EQUAL((T)0, m[0][0]); CPPUNIT_ASSERT_EQUAL((T)0, m[0][1]); CPPUNIT_ASSERT_EQUAL((T)0, m[1][0]); CPPUNIT_ASSERT_EQUAL((T)0, m[1][1]); } + template + void access() { + Matrix m1(1, 2, 3, 4, + 5, 6, 7, 8); + for (size_t row(0); row<2; ++row) + for (size_t column(0); column<4; ++column) + CPPUNIT_ASSERT_EQUAL(m1(row, column), m1[row][column]); + } + template + void equality() { + Matrix m1(1, 2, 3, 4, + 5, 6, 7, 8); + Matrix m2(1, 2, 3, 4, + 5, 6, 7, 8); + Matrix m3(1, 2, 3, 4, + 5, 6, 7, 9); + Matrix m4(9, 2, 3, 4, + 5, 6, 7, 8); + std::cout<