From 714df5dbc01a03e61e97e163c06d693d34277d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Tue, 16 Aug 2016 14:41:22 +0000 Subject: [PATCH] remove redundancy, collect common functionality in base class --- COPYING | 2 +- INSTALL | 2 +- ax_init_standard_project.m4 | 2 +- configure.ac | 2 +- src/matrix.hxx | 415 ++++++++++++++++-------------------- test/basic.cxx | 7 - 6 files changed, 189 insertions(+), 241 deletions(-) diff --git a/COPYING b/COPYING index 88798ab..caeca07 120000 --- a/COPYING +++ b/COPYING @@ -1 +1 @@ -/usr/share/automake-1.15/COPYING \ No newline at end of file +/usr/share/automake-1.14/COPYING \ No newline at end of file diff --git a/INSTALL b/INSTALL index ddcdb76..f812f5a 120000 --- a/INSTALL +++ b/INSTALL @@ -1 +1 @@ -/usr/share/automake-1.15/INSTALL \ No newline at end of file +/usr/share/automake-1.14/INSTALL \ No newline at end of file diff --git a/ax_init_standard_project.m4 b/ax_init_standard_project.m4 index b5840d7..4128d9f 100644 --- a/ax_init_standard_project.m4 +++ b/ax_init_standard_project.m4 @@ -273,7 +273,7 @@ EOF AC_DEFUN([AX_USE_CXX], [ m4_include(ax_cxx_compile_stdcxx_11.m4) AC_LANG(C++) - AX_CXX_COMPILE_STDCXX_14(noext, optional) + AX_CXX_COMPILE_STDCXX_11(noext, optional) AC_PROG_CXX AC_PROG_CPP diff --git a/configure.ac b/configure.ac index da95cdd..318ac2b 100644 --- a/configure.ac +++ b/configure.ac @@ -32,7 +32,7 @@ AX_BUILD_EXAMPLES #AX_CHECK_QT([QT], [QtCore QtGui QtNetwork], [QtWidgets]) #AX_REQUIRE_QT([QT], [QtCore QtGui QtNetwork], [QtWidgets]) #AX_QT_NO_KEYWORDS -AX_REQUIRE_STDCXX_14 +AX_REQUIRE_STDCXX_11 # create output AC_OUTPUT diff --git a/src/matrix.hxx b/src/matrix.hxx index 26e4ee4..c4e20e8 100644 --- a/src/matrix.hxx +++ b/src/matrix.hxx @@ -10,164 +10,8 @@ #include #include -template class Matrix { - - //........................................................const.variables - 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(TYPE); - - //...............................................................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: - TYPE& operator[](size_t column) { - return _v[column]; - } - protected: - friend class Matrix; - RowVector() = delete; // forbidden - RowVector(TYPE c[COLUMNS]): _v(c) {} - TYPE *_v; - }; - - /// Same as RowVector, but in a constant environment. - class ConstRowVector { - public: - const TYPE& operator[](size_t column) const { - return _v[column]; - } - protected: - friend class Matrix; - ConstRowVector() = delete; // forbidden - ConstRowVector(const TYPE c[COLUMNS]): _v(c) {} - const TYPE *_v; - }; +template class MatrixBase { - ///} - - //................................................................methods - public: - - /// @name construction - ///{ - - Matrix() { - memset(_c, 0, MEM_SIZE); - } - - template - Matrix(ARGS...t): _c{std::forward(t)...} { - static_assert(sizeof...(t)==SIZE, "variadic matrix initialisation requires correct array size"); - } - - Matrix(const Matrix& o) { - memcpy(_c, o._c, MEM_SIZE); - } - - ///} - - /// @name operators - ///{ - - Matrix& operator=(TYPE oc[ROWS][COLUMNS]) { - memcpy(_c, oc, MEM_SIZE); - return *this; - } - - Matrix& operator=(const Matrix& o) { - 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) { - 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 { - //..............................................................constants public: @@ -196,10 +40,10 @@ template class Matrix { return _v[column]; } protected: - friend class Matrix; + friend class MatrixBase; RowVector() = delete; // forbidden - RowVector(const Matrix& m, TYPE c[]): _m(m), _v(c) {} - const Matrix& _m; + RowVector(const MatrixBase& m, TYPE c[]): _m(m), _v(c) {} + const MatrixBase& _m; TYPE *_v; }; @@ -211,10 +55,10 @@ template class Matrix { return _v[column]; } protected: - friend class Matrix; + friend class MatrixBase; ConstRowVector() = delete; // forbidden - ConstRowVector(const Matrix& m, const TYPE c[]): _m(m), _v(c) {} - const Matrix& _m; + ConstRowVector(const MatrixBase& m, const TYPE c[]): _m(m), _v(c) {} + const MatrixBase& _m; const TYPE *_v; }; @@ -226,95 +70,55 @@ template class Matrix { /// @name construction ///{ - Matrix(size_t rows, size_t columns): - ROWS(rows), - COLUMNS(columns), - SIZE(rows*columns), - MEM_SIZE(rows*columns*sizeof(TYPE)), - _c(new TYPE[rows*columns]) { - memset(_c, 0, MEM_SIZE); + MatrixBase(size_t rows, size_t columns): + ROWS(rows), COLUMNS(columns), + SIZE(ROWS*COLUMNS), MEM_SIZE(SIZE*sizeof(TYPE)) { } - + template - Matrix(size_t rows, size_t columns, ARGS...t): - Matrix(rows, columns) { - assert(sizeof...(t)==SIZE); - copy_args(_c, t...); + MatrixBase(size_t rows, size_t columns, ARGS...t): + ROWS(rows), COLUMNS(columns), + SIZE(ROWS*COLUMNS), MEM_SIZE(SIZE*sizeof(TYPE)), + _c{std::forward(t)...} { } - Matrix(const Matrix& o): Matrix(o.ROWS, o.COLUMNS) { - memcpy(_c, o._c, MEM_SIZE); - } - - ///} - - /// @name destruction - ///{ - - ~Matrix() { - delete[] _c; - } - ///} /// @name operators ///{ - Matrix& operator=(TYPE oc[]) { + MatrixBase& operator=(TYPE oc[]) { assert(sizeof(oc)==MEM_SIZE); memcpy(_c, oc, MEM_SIZE); return *this; } - Matrix& operator=(const Matrix& o) { - 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 TYPE[SIZE]; - } + MatrixBase& operator=(const MatrixBase& o) { + assert_check(o); memcpy(_c, o._c, MEM_SIZE); return *this; } - bool operator==(const Matrix& o) const { - if (o.ROWS!=ROWS||o.COLUMNS!=COLUMNS) return false; + bool operator==(const MatrixBase& o) const { + if (!check(o)) 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 { + bool operator!=(const MatrixBase& 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) { - assert(o.ROWS==ROWS); - assert(o.COLUMNS==COLUMNS); + MatrixBase& operator+=(const MatrixBase& o) { + assert_check(o); 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); + MatrixBase& operator-=(const MatrixBase& o) { + assert_check(o); TYPE *to((TYPE*)(_c)+SIZE), *from((TYPE*)(o._c)+SIZE); while (to>(TYPE*)(_c)) *--to -= *--from; return *this; @@ -328,23 +132,23 @@ template class Matrix { TYPE& operator()(size_t row, size_t column) { assert(row class Matrix { //................................................................methods protected: + virtual void assert_check(const MatrixBase& o) const {} + virtual bool check(const MatrixBase& o) const { + return true; + } + + //..............................................................variables + protected: + + ARRAY _c; + +}; + +//============================================================================== + +template class Matrix: + public MatrixBase { + + //...............................................................typedefs + private: + + typedef MatrixBase Parent; + + //................................................................methods + public: + + /// @name construction + ///{ + + Matrix(): Parent(TROWS, TCOLUMNS) {} + + template + Matrix(ARGS...t): Parent(TROWS, TCOLUMNS, t...) { + static_assert(sizeof...(t)==TROWS*TCOLUMNS, + "wrong array size"); + } + + Matrix(const Matrix& o): Matrix() { + memcpy(Parent::_c, o._c, Parent::MEM_SIZE); + } + + ///} + + /// @name operators + ///{ + + Matrix& operator=(TYPE oc[TROWS][TCOLUMNS]) { + memcpy(Parent::_c, oc, Parent::MEM_SIZE); + return *this; + } + + Matrix T() const { + Matrix res; + for (size_t row(0); row(TYPE*)(Parent::_c); --to) + *to = -*to; + return res; + } + +}; + +//============================================================================== + +template class Matrix: public MatrixBase { + + //...............................................................typedefs + private: + + typedef MatrixBase Parent; + + //................................................................methods + public: + + /// @name construction + ///{ + + Matrix(size_t rows, size_t columns): + Parent(rows, columns) { + Parent::_c = new TYPE[rows*columns]; + memset(Parent::_c, 0, Parent::MEM_SIZE); + } + + template + Matrix(size_t rows, size_t columns, ARGS...t): + Matrix(rows, columns) { + assert(sizeof...(t)==Parent::SIZE); + copy_args(Parent::_c, t...); + } + + Matrix(const Matrix& o): Matrix(o.ROWS, o.Parent::COLUMNS) { + memcpy(Parent::_c, o.Parent::_c, Parent::MEM_SIZE); + } + + ///} + + /// @name destruction + ///{ + + virtual ~Matrix() { + delete[] Parent::_c; + } + + ///} + + /// @name operators + ///{ + + Matrix& operator=(const Matrix& o) { + if (o.ROWS!=Parent::ROWS&&o.COLUMNS!=Parent::COLUMNS) { + delete[] Parent::_c; + Parent::ROWS = o.ROWS; + Parent::COLUMNS = o.COLUMNS; + Parent::SIZE = o.SIZE; + Parent::MEM_SIZE = o.MEM_SIZE; + Parent::_c = new TYPE[Parent::SIZE]; + } + return Parent::operator=(o); + } + + Matrix T() const { + Matrix res(Parent::COLUMNS, Parent::ROWS); + for (size_t row(0); row(TYPE*)(Parent::_c); --to) + *to = -*to; + return res; + } + + ///} + + //................................................................methods + protected: + + virtual void assert_check(const Matrix& o) const { + assert(o.ROWS==Parent::ROWS); + assert(o.COLUMNS==Parent::COLUMNS); + } + + virtual bool check(const Matrix& o) const { + return o.ROWS==Parent::ROWS && o.COLUMNS==Parent::COLUMNS; + } + void copy_args(TYPE*) {} template void copy_args(TYPE* to, TYPE t1, ARGS...t) { @@ -359,13 +317,10 @@ template class Matrix { copy_args(++to, t...); } - //..............................................................variables - protected: - - TYPE* _c; - }; +//============================================================================== + template Matrix operator+(const Matrix& m1, const Matrix& m2) { Matrix res(m1); diff --git a/test/basic.cxx b/test/basic.cxx index 7e29e7f..fce9437 100644 --- a/test/basic.cxx +++ b/test/basic.cxx @@ -105,13 +105,6 @@ class TemplateMatrixTest: public CppUnit::TestFixture { 5, 6, 7, 9); Matrix m4(9, 2, 3, 4, 5, 6, 7, 8); - std::cout<