From b54af4681a77a960607ce3b0163212733632e842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20W=C3=A4ckerlin?= Date: Wed, 3 Aug 2016 18:39:03 +0000 Subject: [PATCH] first approach including first tests --- COPYING | 1 + ChangeLog | 16 ++ INSTALL | 1 + ax_cxx_compile_stdcxx_11.m4 | 97 +++++++++++- ax_init_standard_project.m4 | 2 +- configure.ac | 1 + examples/makefile.am | 6 +- examples/matrix-sample.cxx | 23 +++ src/makefile.am | 2 + src/matrix.hxx | 299 ++++++++++++++++++++++++++++++++++++ test/basic.cxx | 215 ++++++++++++++++++++++++++ test/makefile.am | 8 +- 12 files changed, 666 insertions(+), 5 deletions(-) create mode 120000 COPYING create mode 120000 INSTALL create mode 100644 examples/matrix-sample.cxx create mode 100644 src/matrix.hxx create mode 100644 test/basic.cxx diff --git a/COPYING b/COPYING new file mode 120000 index 0000000..88798ab --- /dev/null +++ b/COPYING @@ -0,0 +1 @@ +/usr/share/automake-1.15/COPYING \ No newline at end of file diff --git a/ChangeLog b/ChangeLog index e69de29..df7a739 100644 --- a/ChangeLog +++ b/ChangeLog @@ -0,0 +1,16 @@ +2016-07-30 08:50 + + * ., AUTHORS, ChangeLog, NEWS, README, autogen.sh, ax_check_qt.m4, + ax_cxx_compile_stdcxx_11.m4, ax_init_standard_project.m4, + bootstrap.sh, build-in-docker.conf, build-in-docker.sh, + build-resource-file.sh, configure.ac, debian, + debian/changelog.in, debian/compat, debian/control.in, + debian/docs, debian/libmatricxx-dev.install, + debian/libmatricxx.install, debian/rules, doc, doc/doxyfile.in, + doc/makefile.am, examples, examples/makefile.am, + libmatricxx.desktop.in, libmatricxx.spec.in, + mac-create-app-bundle.sh, makefile.am, resolve-debbuilddeps.sh, + resolve-rpmbuilddeps.sh, sql-to-dot.sed, src, + src/libmatricxx.pc.in, src/makefile.am, src/version.cxx, + src/version.hxx, test, test/makefile.am: initial project + diff --git a/INSTALL b/INSTALL new file mode 120000 index 0000000..ddcdb76 --- /dev/null +++ b/INSTALL @@ -0,0 +1 @@ +/usr/share/automake-1.15/INSTALL \ No newline at end of file diff --git a/ax_cxx_compile_stdcxx_11.m4 b/ax_cxx_compile_stdcxx_11.m4 index af37acd..e3fc158 100644 --- a/ax_cxx_compile_stdcxx_11.m4 +++ b/ax_cxx_compile_stdcxx_11.m4 @@ -4,12 +4,16 @@ # # SYNOPSIS # +# AX_REQUIRE_STDCXX_11 +# AX_REQUIRE_STDCXX_14 # AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) +# AX_CXX_COMPILE_STDCXX_14([ext|noext],[mandatory|optional]) # # DESCRIPTION # # Check for baseline language coverage in the compiler for the C++11 -# standard; if necessary, add switches to CXXFLAGS to enable support. +# or C++14 standard; if necessary, add switches to CXXFLAGS to +# enable support. # # The first argument, if specified, indicates whether you insist on an # extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. @@ -131,3 +135,94 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl AC_SUBST(HAVE_CXX11) fi ]) + +AC_DEFUN([AX_CXX_COMPILE_STDCXX_14], [dnl + m4_if([$1], [], [], + [$1], [ext], [], + [$1], [noext], [], + [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_14])])dnl + m4_if([$2], [], [ax_cxx_compile_cxx14_required=true], + [$2], [mandatory], [ax_cxx_compile_cxx14_required=true], + [$2], [optional], [ax_cxx_compile_cxx14_required=false], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_14])])dnl + AC_LANG_PUSH([C++])dnl + ac_success=no + AC_CACHE_CHECK(whether $CXX supports C++14 features by default, + ax_cv_cxx_compile_cxx14, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [ax_cv_cxx_compile_cxx14=yes], + [ax_cv_cxx_compile_cxx14=no])]) + if test x$ax_cv_cxx_compile_cxx14 = xyes; then + ac_success=yes + fi + + m4_if([$1], [noext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=gnu++14 -std=gnu++0y; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx14_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++14 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + + m4_if([$1], [ext], [], [dnl + if test x$ac_success = xno; then + for switch in -std=c++14 -std=c++0y; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx14_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++14 features with $switch, + $cachevar, + [ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXXFLAGS="$ac_save_CXXFLAGS"]) + if eval test x\$$cachevar = xyes; then + CXXFLAGS="$CXXFLAGS $switch" + ac_success=yes + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx14_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++14 language features is required.]) + fi + else + if test x$ac_success = xno; then + HAVE_CXX14=0 + AC_MSG_NOTICE([No compiler with C++14 support was found]) + else + HAVE_CXX14=1 + AC_DEFINE(HAVE_CXX14,1, + [define if the compiler supports basic C++14 syntax]) + fi + HAVE_CXX11=${HAVE_CXX14} + AC_SUBST(HAVE_CXX11) + AC_SUBST(HAVE_CXX14) + fi +]) + +AC_DEFUN([AX_REQUIRE_STDCXX_11], [ + if test x${HAVE_CXX11} != x1; then + AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) + fi +]) + +AC_DEFUN([AX_REQUIRE_STDCXX_14], [ + if test x${HAVE_CXX14} != x1; then + AC_MSG_ERROR([*** A compiler with support for C++14 language features is required.]) + fi +]) diff --git a/ax_init_standard_project.m4 b/ax_init_standard_project.m4 index 4128d9f..b5840d7 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_11(noext, optional) + AX_CXX_COMPILE_STDCXX_14(noext, optional) AC_PROG_CXX AC_PROG_CPP diff --git a/configure.ac b/configure.ac index 4452a41..d787175 100644 --- a/configure.ac +++ b/configure.ac @@ -32,6 +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 # create output AC_OUTPUT diff --git a/examples/makefile.am b/examples/makefile.am index 179bb99..ac29969 100644 --- a/examples/makefile.am +++ b/examples/makefile.am @@ -10,6 +10,10 @@ AM_CPPFLAGS = -I${top_srcdir}/src -I${top_builddir}/src AM_LDFLAGS = -L${abs_top_builddir}/src/.libs -LDADD = -lmatricxx +#LDADD = -lmatricxx + +noinst_PROGRAMS = matrix-sample + +matrix_sample_SOURCES = matrix-sample.cxx MAINTAINERCLEANFILES = makefile.in diff --git a/examples/matrix-sample.cxx b/examples/matrix-sample.cxx new file mode 100644 index 0000000..6212f30 --- /dev/null +++ b/examples/matrix-sample.cxx @@ -0,0 +1,23 @@ +/*! @file + + @id $Id$ +*/ +// 1 2 3 4 5 6 7 8 +// 45678901234567890123456789012345678901234567890123456789012345678901234567890 + +#include + +int main(int, char**) { + // Matrix m1{1, 2, 3, 4, + // 5, 6, 7, 8, + // 9, 10, 11, 12}; + // std::cout<<"m1 = "< m2 = m1; + // std::cout<<"m1 = "< m3; + // m3 = m1 + m2; + // std::cout<<"m1 = "<(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< +#include +#include +#include +#include +#include +#include + +class TemplateMatrixTest: public CppUnit::TestFixture { + public: + template + void initFromArray1() { + Matrix m {1, 2, 3, 4, + 5, 6, 7, 8}; + CPPUNIT_ASSERT_EQUAL((T)1, m[0][0]); + CPPUNIT_ASSERT_EQUAL((T)2, m[0][1]); + CPPUNIT_ASSERT_EQUAL((T)3, m[0][2]); + CPPUNIT_ASSERT_EQUAL((T)4, m[0][3]); + CPPUNIT_ASSERT_EQUAL((T)5, m[1][0]); + CPPUNIT_ASSERT_EQUAL((T)6, m[1][1]); + CPPUNIT_ASSERT_EQUAL((T)7, m[1][2]); + CPPUNIT_ASSERT_EQUAL((T)8, m[1][3]); + } + template + void initFromArray2() { + Matrix m(1, 2, 3, 4, + 5, 6, 7, 8); + CPPUNIT_ASSERT_EQUAL((T)1, m[0][0]); + CPPUNIT_ASSERT_EQUAL((T)2, m[0][1]); + CPPUNIT_ASSERT_EQUAL((T)3, m[0][2]); + CPPUNIT_ASSERT_EQUAL((T)4, m[0][3]); + CPPUNIT_ASSERT_EQUAL((T)5, m[1][0]); + CPPUNIT_ASSERT_EQUAL((T)6, m[1][1]); + CPPUNIT_ASSERT_EQUAL((T)7, m[1][2]); + CPPUNIT_ASSERT_EQUAL((T)8, m[1][3]); + } + template + void initFromArray3() { + Matrix m({1, 2, 3, 4, + 5, 6, 7, 8}); + CPPUNIT_ASSERT_EQUAL((T)1, m[0][0]); + CPPUNIT_ASSERT_EQUAL((T)2, m[0][1]); + CPPUNIT_ASSERT_EQUAL((T)3, m[0][2]); + CPPUNIT_ASSERT_EQUAL((T)4, m[0][3]); + CPPUNIT_ASSERT_EQUAL((T)5, m[1][0]); + CPPUNIT_ASSERT_EQUAL((T)6, m[1][1]); + CPPUNIT_ASSERT_EQUAL((T)7, m[1][2]); + CPPUNIT_ASSERT_EQUAL((T)8, m[1][3]); + } + template + void initFromOtherMatrix() { + Matrix m1(1, 2, 3, 4, + 5, 6, 7, 8); + m1[1][2] = 13; + Matrix m2(m1); + m1[0][2] = 16; + m2[0][0] = 0; + CPPUNIT_ASSERT_EQUAL((T)1, m1[0][0]); + CPPUNIT_ASSERT_EQUAL((T)2, m1[0][1]); + CPPUNIT_ASSERT_EQUAL((T)16, m1[0][2]); + CPPUNIT_ASSERT_EQUAL((T)4, m1[0][3]); + CPPUNIT_ASSERT_EQUAL((T)5, m1[1][0]); + CPPUNIT_ASSERT_EQUAL((T)6, m1[1][1]); + CPPUNIT_ASSERT_EQUAL((T)13, m1[1][2]); + CPPUNIT_ASSERT_EQUAL((T)8, m1[1][3]); + CPPUNIT_ASSERT_EQUAL((T)0, m2[0][0]); + CPPUNIT_ASSERT_EQUAL((T)2, m2[0][1]); + CPPUNIT_ASSERT_EQUAL((T)3, m2[0][2]); + CPPUNIT_ASSERT_EQUAL((T)4, m2[0][3]); + CPPUNIT_ASSERT_EQUAL((T)5, m2[1][0]); + CPPUNIT_ASSERT_EQUAL((T)6, m2[1][1]); + CPPUNIT_ASSERT_EQUAL((T)13, m2[1][2]); + CPPUNIT_ASSERT_EQUAL((T)8, m2[1][3]); + } + template + 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]); + } + CPPUNIT_TEST_SUITE(TemplateMatrixTest); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray3); + CPPUNIT_TEST(initFromArray3); + CPPUNIT_TEST(initFromArray3); + CPPUNIT_TEST(initFromArray3); + CPPUNIT_TEST(initFromArray3); + CPPUNIT_TEST(initFromArray3); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST_SUITE_END(); +}; +CPPUNIT_TEST_SUITE_REGISTRATION(TemplateMatrixTest); + +class VariableMatrixTest: public CppUnit::TestFixture { + public: + template + void initFromArray1() { + Matrix m(2,4, + 1, 2, 3, 4, + 5, 6, 7, 8); + CPPUNIT_ASSERT_EQUAL((T)1, m[0][0]); + CPPUNIT_ASSERT_EQUAL((T)2, m[0][1]); + CPPUNIT_ASSERT_EQUAL((T)3, m[0][2]); + CPPUNIT_ASSERT_EQUAL((T)4, m[0][3]); + CPPUNIT_ASSERT_EQUAL((T)5, m[1][0]); + CPPUNIT_ASSERT_EQUAL((T)6, m[1][1]); + CPPUNIT_ASSERT_EQUAL((T)7, m[1][2]); + CPPUNIT_ASSERT_EQUAL((T)8, m[1][3]); + } + template + void initFromArray2() { + Matrix m(2, 4, + 1, 2, 3, 4, + 5, 6, 7, 8); + CPPUNIT_ASSERT_EQUAL((T)1, m[0][0]); + CPPUNIT_ASSERT_EQUAL((T)2, m[0][1]); + CPPUNIT_ASSERT_EQUAL((T)3, m[0][2]); + CPPUNIT_ASSERT_EQUAL((T)4, m[0][3]); + CPPUNIT_ASSERT_EQUAL((T)5, m[1][0]); + CPPUNIT_ASSERT_EQUAL((T)6, m[1][1]); + CPPUNIT_ASSERT_EQUAL((T)7, m[1][2]); + CPPUNIT_ASSERT_EQUAL((T)8, m[1][3]); + } + template + void initFromOtherMatrix() { + Matrix m1(2, 4, + 1, 2, 3, 4, + 5, 6, 7, 8); + m1[1][2] = 13; + Matrix m2(m1); + m1[0][2] = 16; + m2[0][0] = 0; + CPPUNIT_ASSERT_EQUAL((T)1, m1[0][0]); + CPPUNIT_ASSERT_EQUAL((T)2, m1[0][1]); + CPPUNIT_ASSERT_EQUAL((T)16, m1[0][2]); + CPPUNIT_ASSERT_EQUAL((T)4, m1[0][3]); + CPPUNIT_ASSERT_EQUAL((T)5, m1[1][0]); + CPPUNIT_ASSERT_EQUAL((T)6, m1[1][1]); + CPPUNIT_ASSERT_EQUAL((T)13, m1[1][2]); + CPPUNIT_ASSERT_EQUAL((T)8, m1[1][3]); + CPPUNIT_ASSERT_EQUAL((T)0, m2[0][0]); + CPPUNIT_ASSERT_EQUAL((T)2, m2[0][1]); + CPPUNIT_ASSERT_EQUAL((T)3, m2[0][2]); + CPPUNIT_ASSERT_EQUAL((T)4, m2[0][3]); + CPPUNIT_ASSERT_EQUAL((T)5, m2[1][0]); + CPPUNIT_ASSERT_EQUAL((T)6, m2[1][1]); + CPPUNIT_ASSERT_EQUAL((T)13, m2[1][2]); + CPPUNIT_ASSERT_EQUAL((T)8, m2[1][3]); + } + template + void initFromDefault() { + Matrix m(2, 4); + 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]); + } + CPPUNIT_TEST_SUITE(VariableMatrixTest); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray1); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromArray2); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST(initFromOtherMatrix); + CPPUNIT_TEST_SUITE_END(); +}; +CPPUNIT_TEST_SUITE_REGISTRATION(VariableMatrixTest); + +int main(int argc, char** argv) try { + std::ofstream ofs((*argv+std::string(".xml")).c_str()); + CppUnit::TextUi::TestRunner runner; + runner.setOutputter(new CppUnit::XmlOutputter(&runner.result(), ofs)); + runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); + return runner.run() ? 0 : 1; + } catch (std::exception& e) { + std::cerr<<"***Exception: "<