From a8088d03cd983fe8e32dc50d0a7c302956f41452 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Fri, 24 Nov 2017 13:08:56 +1100 Subject: [PATCH] matrix: use vector for the row storage --- coord/base.hpp | 17 ++++++++++---- coord/ops.hpp | 15 +++++------- matrix.cpp | 2 +- matrix.hpp | 61 ++++++++++++++++++++++++++++++------------------- test/affine.cpp | 3 --- test/matrix.cpp | 4 ++-- 6 files changed, 59 insertions(+), 43 deletions(-) diff --git a/coord/base.hpp b/coord/base.hpp index c2ff6ced..736741ad 100644 --- a/coord/base.hpp +++ b/coord/base.hpp @@ -73,13 +73,20 @@ namespace util::coord { } constexpr base (const base &rhs) = default; - base& operator= (const base &rhs) = default; + base& operator= (const base &rhs)& = default; + base& operator= (const T t)& + { + for (auto v: *this) + v = t; + return *this; + } // element accessors - T& operator[] (size_t i) { return this->data[i]; } - constexpr const T& operator[] (size_t i) const { return this->data[i]; } - T& operator[] (int i) { return this->data[i]; } - constexpr const T& operator[] (int i) const { return this->data[i]; } + constexpr T& operator[] (size_t i)& noexcept { return this->data[i]; } + constexpr T& operator[] (int i)& noexcept { return this->data[i]; } + + constexpr const T& operator[] (size_t i) const& noexcept { return this->data[i]; } + constexpr const T& operator[] (int i) const& noexcept { return this->data[i]; } auto cbegin (void) const { return std::cbegin (this->data); } auto cend (void) const { return std::cend (this->data); } diff --git a/coord/ops.hpp b/coord/ops.hpp index a3967d12..1ca9e3f8 100644 --- a/coord/ops.hpp +++ b/coord/ops.hpp @@ -609,19 +609,16 @@ namespace util { //------------------------------------------------------------------------- template < - std::size_t S, - typename T, - template class A, - template class B, + typename A, + typename B, typename = std::enable_if_t< - is_coord_v> && is_coord_v>, void + is_coord_v && is_coord_v, void > > - constexpr - T - dot (A a, B b) + constexpr auto + dot (A a, B b) { - return dot (a.data, b.data); + return dot (a.data, b.data); } diff --git a/matrix.cpp b/matrix.cpp index de04b8ef..d95f51df 100644 --- a/matrix.cpp +++ b/matrix.cpp @@ -352,7 +352,7 @@ util::operator<< (std::ostream &os, const matrix &m) for (std::size_t i = 0; i < Rows; ++i) { os << "{ "; - std::copy_n (m[i], Cols, util::infix_iterator (os, ", ")); + std::copy (std::cbegin (m[i]), std::cend (m[i]), util::infix_iterator (os, ", ")); os << ((i == Rows - 1) ? " }" : " }, "); } diff --git a/matrix.hpp b/matrix.hpp index fb5d702b..d8b65063 100644 --- a/matrix.hpp +++ b/matrix.hpp @@ -34,17 +34,25 @@ namespace util { static constexpr auto rows = Rows; static constexpr auto cols = Cols; + using row_t = util::vector; + + + /////////////////////////////////////////////////////////////////////// constexpr matrix () noexcept = default; + + //--------------------------------------------------------------------- constexpr matrix (const T(&_data)[Rows][Cols]) noexcept: values {} { + static_assert (sizeof (*this) == sizeof (T) * Rows * Cols); for (std::size_t r = 0; r < Rows; ++r) for (std::size_t c = 0; c < Cols; ++c) values[r][c] = _data[r][c]; } + //--------------------------------------------------------------------- template constexpr matrix (const util::coord::base (&_data)[Rows]) noexcept { @@ -53,55 +61,54 @@ namespace util { values[r][c] = _data[r][c]; } - T values[Rows][Cols]; /////////////////////////////////////////////////////////////////////// // index operators return a pointer into the data array so that // multidimensional array syntax can be used transparently on this // type. - constexpr auto& operator[] (std::size_t idx) { return values[idx]; } - constexpr const auto& operator[] (std::size_t idx) const { return values[idx]; } + constexpr row_t& operator[] (std::size_t idx)& { return values[idx]; } + constexpr const row_t& operator[] (std::size_t idx) const& { return values[idx]; } //--------------------------------------------------------------------- - constexpr auto + constexpr row_t* data (void)& noexcept { - return begin (); + return &values[0]; } //--------------------------------------------------------------------- - constexpr auto + constexpr const row_t* data (void) const& noexcept { - return begin (); + return &values[0]; } //--------------------------------------------------------------------- constexpr auto begin (void) const& noexcept { - return &(*this)[0][0]; - } - - //--------------------------------------------------------------------- - constexpr auto - end (void) const& noexcept - { - return &(*this)[Rows][0]; + return data (); } //--------------------------------------------------------------------- constexpr auto begin (void)& noexcept { - return &(*this)[0][0]; + return data (); } //--------------------------------------------------------------------- - constexpr auto + constexpr row_t* end (void)& noexcept { - return &(*this)[Rows][0]; + return &values[Rows]; + } + + //--------------------------------------------------------------------- + constexpr const row_t* + end (void) const& noexcept + { + return &values[Rows]; } //--------------------------------------------------------------------- @@ -138,8 +145,8 @@ namespace util { { VectorT out; - for (std::size_t i = 0; i < Rows; ++i) - out[i] = dot (rhs, values[i]); + for (std::size_t r = 0; r < Rows; ++r) + out[r] = dot (rhs, values[r]); return out; } @@ -169,9 +176,13 @@ namespace util { matrix zeroes (void) noexcept { matrix ret {}; - std::fill (std::begin (ret), std::end (ret), T{0}); + std::fill (std::begin (ret), std::end (ret), row_t{0}); return ret; } + + + private: + row_t values[Rows]; }; @@ -346,7 +357,8 @@ namespace util { abs (const matrix &src) { matrix dst; - std::transform (std::cbegin (src), std::cend (src), std::begin (dst), util::abs); + for (size_t r = 0; r < Rows; ++r) + dst[r] = abs (src[r]); return dst; } @@ -355,7 +367,10 @@ namespace util { constexpr T sum (const matrix &src) { - return sum (std::cbegin (src), std::cend (src)); + util::vector accum {}; + for (size_t r = 0; r < Rows; ++r) + accum[r] = sum (src[r]); + return sum (accum); } diff --git a/test/affine.cpp b/test/affine.cpp index a7208972..b68e2ef4 100644 --- a/test/affine.cpp +++ b/test/affine.cpp @@ -104,9 +104,6 @@ test_mq_euler (util::TAP::logger &tap) util::quaternionf::angle_axis (t.z, { 0, 0, 1 }) ).as_matrix (); - if (abs (m - q)[0]) - exit (0); - auto diff = util::sum (abs (m - q)); tap.expect_le (diff, 1e-6f, "matrix-quaternion xyz euler rotations, %s", t.msg); } diff --git a/test/matrix.cpp b/test/matrix.cpp index 40e8d94d..dc962a71 100644 --- a/test/matrix.cpp +++ b/test/matrix.cpp @@ -112,9 +112,9 @@ main (void) for (size_t r = 0; r < m.rows; ++r) for (size_t c = 0; c < m.cols; ++c) if (r == c) - success = success && util::almost_equal (m.values[r][c], 1.f); + success = success && util::almost_equal (m[r][c], 1.f); else - success = success && util::almost_equal (m.values[r][c], 0.f); + success = success && util::almost_equal (m[r][c], 0.f); tap.expect (success, "identity inversion"); }