diff --git a/CMakeLists.txt b/CMakeLists.txt index 3664382d..4f806b76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -329,7 +329,6 @@ list ( matrix3.cpp matrix4.cpp matrix.hpp - matrix.ipp memory/deleter.cpp memory/deleter.hpp nocopy.hpp diff --git a/matrix.hpp b/matrix.hpp index e3597214..fb5d702b 100644 --- a/matrix.hpp +++ b/matrix.hpp @@ -25,7 +25,11 @@ #include namespace util { - template + template < + std::size_t Rows, + std::size_t Cols, + typename T + > struct matrix { static constexpr auto rows = Rows; static constexpr auto cols = Cols; @@ -49,7 +53,7 @@ namespace util { values[r][c] = _data[r][c]; } - T values[rows][cols]; + T values[Rows][Cols]; /////////////////////////////////////////////////////////////////////// // index operators return a pointer into the data array so that @@ -60,56 +64,56 @@ namespace util { //--------------------------------------------------------------------- constexpr auto - data (void) noexcept + data (void)& noexcept { return begin (); } //--------------------------------------------------------------------- constexpr auto - data (void) const noexcept + data (void) const& noexcept { return begin (); } //--------------------------------------------------------------------- constexpr auto - begin (void) const noexcept + begin (void) const& noexcept { return &(*this)[0][0]; } //--------------------------------------------------------------------- constexpr auto - end (void) const noexcept + end (void) const& noexcept { return &(*this)[Rows][0]; } //--------------------------------------------------------------------- constexpr auto - begin (void) noexcept + begin (void)& noexcept { return &(*this)[0][0]; } //--------------------------------------------------------------------- constexpr auto - end (void) noexcept + end (void)& noexcept { return &(*this)[Rows][0]; } //--------------------------------------------------------------------- constexpr auto - cbegin (void) const noexcept + cbegin (void) const& noexcept { return begin (); } //--------------------------------------------------------------------- constexpr auto - cend (void) const noexcept + cend (void) const& noexcept { return end (); } @@ -146,14 +150,28 @@ namespace util { matrix cast (void) const noexcept { - util::matrix out; + matrix out; std::copy (cbegin (), cend (), std::begin (out)); return out; } // Constant matrices - static constexpr matrix identity (); - static constexpr matrix zeroes (); + static constexpr + matrix identity (void) noexcept + { + auto m = zeroes (); + for (std::size_t i = 0; i < Rows; ++i) + m[i][i] = 1; + return m; + } + + static constexpr + matrix zeroes (void) noexcept + { + matrix ret {}; + std::fill (std::begin (ret), std::end (ret), T{0}); + return ret; + } }; @@ -164,10 +182,10 @@ namespace util { template matrix<4,4,T> look_at (point<3,T> eye, point<3,T> target, vector<3,T> up); // Affine matrices - template matrix<4,4,T> translation (util::vector<3,T>); - template matrix<4,4,T> scale (util::vector<3,T>); + template matrix<4,4,T> translation (vector<3,T>); + template matrix<4,4,T> scale (vector<3,T>); template matrix<4,4,T> scale (T); - template matrix<4,4,T> rotation (T angle, util::vector<3,T> about); + template matrix<4,4,T> rotation (T angle, vector<3,T> about); /////////////////////////////////////////////////////////////////////////// @@ -185,13 +203,20 @@ namespace util { template constexpr bool - operator== (const matrix&, const matrix&); + operator== (const matrix &a, const matrix &b) + { + return std::equal (std::cbegin (a), std::cend (a), std::cbegin (b)); + } + //------------------------------------------------------------------------- template constexpr bool - operator!= (const matrix&, const matrix&); + operator!= (const matrix &a, const matrix &b) + { + return !(a == b); + } /////////////////////////////////////////////////////////////////////////// @@ -302,24 +327,112 @@ namespace util { T determinant (const matrix&); + + //------------------------------------------------------------------------- template matrix inverse (const matrix&); + + //------------------------------------------------------------------------- template matrix transposed (const matrix&); - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// template matrix - abs (const matrix&); + abs (const matrix &src) + { + matrix dst; + std::transform (std::cbegin (src), std::cend (src), std::begin (dst), util::abs); + return dst; + } + template - constexpr - T - sum (const matrix&); + constexpr T + sum (const matrix &src) + { + return sum (std::cbegin (src), std::cend (src)); + } + + + /////////////////////////////////////////////////////////////////////////// + #define MATRIX_ELEMENT_OP(OP) \ + template \ + constexpr \ + matrix \ + operator OP ( \ + const matrix &a, \ + const matrix &b) \ + { \ + matrix res {}; \ + \ + for (std::size_t i = 0; i < a.rows; ++i) \ + for (std::size_t j = 0; j < a.cols; ++j) \ + res[i][j] = a[i][j] OP b[i][j]; \ + \ + return res; \ + } + + MATRIX_ELEMENT_OP(-) + MATRIX_ELEMENT_OP(+) + + #undef MATRIX_ELEMENT_OP + + + /////////////////////////////////////////////////////////////////////////// + #define MATRIX_SCALAR_OP(OP) \ + template \ + constexpr \ + matrix \ + operator OP (const matrix &m, const T t) \ + { \ + matrix res {}; \ + \ + std::transform ( \ + std::cbegin (m), \ + std::cend (m), \ + std::begin (res), \ + [&t] (auto x) { return x OP t; } \ + ); \ + \ + return res; \ + } \ + \ + \ + template \ + constexpr \ + matrix \ + operator OP (const T t, const matrix &m) \ + { \ + return m OP t; \ + } \ + \ + \ + template \ + constexpr \ + matrix& \ + operator OP##= (matrix &m, T t) \ + { \ + std::transform ( \ + std::cbegin (m), \ + std::cend (m), \ + std::begin (m), \ + [&t] (auto x) { return x OP t; } \ + ); \ + \ + return m; \ + } + + MATRIX_SCALAR_OP(*) + MATRIX_SCALAR_OP(/) + MATRIX_SCALAR_OP(+) + MATRIX_SCALAR_OP(-) + + #undef MATRIX_SCALAR_OP /////////////////////////////////////////////////////////////////////////// @@ -342,8 +455,8 @@ namespace util { /////////////////////////////////////////////////////////////////////////// template std::ostream& operator<< (std::ostream&, const matrix&); + + } -#include "matrix.ipp" - #endif diff --git a/matrix.ipp b/matrix.ipp deleted file mode 100644 index 9fc75048..00000000 --- a/matrix.ipp +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * Copyright 2011-2015 Danny Robson - */ - - -#ifdef __UTIL_MATRIX_IPP -#error -#endif - -#include "matrix.hpp" -#define __UTIL_MATRIX_IPP - - -/////////////////////////////////////////////////////////////////////////////// -//template -//T* -//util::matrix::operator[] (int idx) -//{ -// return this->values[idx]; -//} -// -// -////----------------------------------------------------------------------------- -//template -//const T* -//util::matrix::operator[] (int idx) const -//{ -// return this->values[idx]; -//} - - -/////////////////////////////////////////////////////////////////////////////// -#define MATRIX_ELEMENT_OP(OP) \ -template \ -constexpr \ -util::matrix \ -util::operator OP ( \ - const util::matrix &a, \ - const util::matrix &b) \ -{ \ - util::matrix res {}; \ - \ - for (std::size_t i = 0; i < a.rows; ++i) \ - for (std::size_t j = 0; j < a.cols; ++j) \ - res[i][j] = a[i][j] OP b[i][j]; \ - \ - return res; \ -} - -MATRIX_ELEMENT_OP(-) -MATRIX_ELEMENT_OP(+) - -#undef MATRIX_ELEMENT_OP - - -/////////////////////////////////////////////////////////////////////////////// -#define MATRIX_SCALAR_OP(OP) \ -template \ -constexpr \ -util::matrix \ -util::operator OP (const util::matrix &m, const T t) \ -{ \ - util::matrix res {}; \ - \ - std::transform ( \ - std::cbegin (m), \ - std::cend (m), \ - std::begin (res), \ - [&t] (auto x) { return x OP t; } \ - ); \ - \ - return res; \ -} \ - \ - \ -template \ -constexpr \ -util::matrix \ -util::operator OP (const T t, const util::matrix &m) \ -{ \ - return m OP t; \ -} \ - \ - \ -template \ -constexpr \ -util::matrix& \ -util::operator OP##= (util::matrix &m, T t) \ -{ \ - std::transform ( \ - std::cbegin (m), \ - std::cend (m), \ - std::begin (m), \ - [&t] (auto x) { return x OP t; } \ - ); \ - \ - return m; \ -} - - -MATRIX_SCALAR_OP(*) -MATRIX_SCALAR_OP(/) -MATRIX_SCALAR_OP(+) -MATRIX_SCALAR_OP(-) - -#undef MATRIX_SCALAR_OP - - -/////////////////////////////////////////////////////////////////////////////// -template -constexpr -util::matrix -util::matrix::zeroes (void) -{ - util::matrix ret {}; - for (std::size_t r = 0; r < Rows; ++r) - for (std::size_t c = 0; c < Cols; ++c) - ret[r][c] = 0; - return ret; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -constexpr -util::matrix -util::matrix::identity (void) -{ - static_assert (Rows == Cols); - - auto m = zeroes (); - for (std::size_t i = 0; i < Rows; ++i) - m[i][i] = 1; - return m; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -constexpr -bool -util::operator== (const matrix &a, const matrix &b) -{ - return std::equal (std::cbegin (a), std::cend (a), std::cbegin (b)); -} - - -//----------------------------------------------------------------------------- -template -constexpr -bool -util::operator!= (const matrix &a, const matrix &b) -{ - return !(a == b); -} - - -/////////////////////////////////////////////////////////////////////////////// -template -util::matrix -util::abs (const util::matrix &src) -{ - util::matrix dst; - std::transform (std::cbegin (src), std::cend (src), std::begin (dst), util::abs); - return dst; -} - - -/////////////////////////////////////////////////////////////////////////////// -template -constexpr -T -util::sum (const util::matrix &src) -{ - return sum (std::cbegin (src), std::cend (src)); -} diff --git a/test/matrix.cpp b/test/matrix.cpp index 0e077098..40e8d94d 100644 --- a/test/matrix.cpp +++ b/test/matrix.cpp @@ -15,6 +15,13 @@ main (void) { util::TAP::logger tap; + // a quick check to make sure this function is actually provided + tap.expect_eq (sum (util::matrix4f::zeroes ()), 0.f, "zero matrix sums to zero"); + + + // trivial check for matrix summation. useful to sanity test some + // alignment constraints if run under a tool like memorysanitizer or + // valgrind. static constexpr util::matrix4f SEQ { { { 1, 2, 3, 4 }, { 5, 6, 7, 8 },