diff --git a/README.md b/README.md index 248db58..7c703dc 100644 --- a/README.md +++ b/README.md @@ -1769,13 +1769,13 @@ template < typename T, size_t Size > T component(const vec& v, size_t index); template < typename T, size_t Size > -vec component(vec v, size_t index, T x); +vec component(const vec& v, size_t index, T x); template < typename T, size_t Size > vec row(const mat& m, size_t index); template < typename T, size_t Size > -mat row(mat m, size_t index, const vec& v); +mat row(const mat& m, size_t index, const vec& v); template < typename T, size_t Size > vec column(const mat& m, size_t index); @@ -1783,6 +1783,12 @@ vec column(const mat& m, size_t index); template < typename T, size_t Size > mat column(const mat& m, size_t index, const vec& v); +template < typename T, size_t Size > +vec diagonal(const mat& m); + +template < typename T, size_t Size > +mat diagonal(const mat& m, const vec& diagonal); + template < typename T > T real(const qua& q); diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index af55c0f..9c54312 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -152,9 +152,10 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec component(vec v, std::size_t index, T component) { - v[index] = component; - return v; + [[nodiscard]] constexpr vec component(const vec& v, std::size_t index, T component) { + vec vv = v; + vv[index] = component; + return vv; } // row @@ -165,9 +166,10 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat row(mat m, std::size_t index, const vec& row) { - m.rows[index] = row; - return m; + [[nodiscard]] constexpr mat row(const mat& m, std::size_t index, const vec& row) { + mat mm = m; + mm[index] = row; + return mm; } // column @@ -197,6 +199,31 @@ namespace vmath_hpp return impl::column_impl(m, index, column, std::make_index_sequence{}); } + // diagonal + + namespace impl + { + template < typename T, std::size_t Size, std::size_t... Is > + [[nodiscard]] constexpr vec diagonal_impl(const mat& m, std::index_sequence) { + return { m[Is][Is]... }; + } + + template < typename T, std::size_t Size, std::size_t... Is > + [[nodiscard]] constexpr mat diagonal_impl(const mat& m, const vec& diagonal, std::index_sequence) { + return { component(m[Is], Is, diagonal[Is])... }; + } + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec diagonal(const mat& m) { + return impl::diagonal_impl(m, std::make_index_sequence{}); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat diagonal(const mat& m, const vec& diagonal) { + return impl::diagonal_impl(m, diagonal, std::make_index_sequence{}); + } + // real template < typename T > diff --git a/untests/CMakeLists.txt b/untests/CMakeLists.txt index 0220203..edc5959 100644 --- a/untests/CMakeLists.txt +++ b/untests/CMakeLists.txt @@ -18,7 +18,7 @@ endif() file(GLOB_RECURSE UNTESTS_SOURCES "*.cpp" "*.hpp") add_executable(${PROJECT_NAME} ${UNTESTS_SOURCES}) -target_link_libraries(${PROJECT_NAME} vmath.hpp.singles) +target_link_libraries(${PROJECT_NAME} vmath.hpp) target_compile_options(${PROJECT_NAME} PRIVATE diff --git a/untests/vmath_ext_tests.cpp b/untests/vmath_ext_tests.cpp index 2ca03e0..73eff9c 100644 --- a/untests/vmath_ext_tests.cpp +++ b/untests/vmath_ext_tests.cpp @@ -205,6 +205,14 @@ TEST_CASE("vmath/ext/access") { STATIC_CHECK(column(imat2(), 1, {3,4}) == imat2(1,3,0,4)); } + SUBCASE("diagonal") { + STATIC_CHECK(diagonal(imat2(1,2,3,4)) == ivec2(1,4)); + STATIC_CHECK(diagonal(imat2(1,2,3,4), ivec2(10,40)) == imat2(10,2,3,40)); + + STATIC_CHECK(diagonal(imat3(1,2,3,4,5,6,7,8,9)) == ivec3(1,5,9)); + STATIC_CHECK(diagonal(imat3(1,2,3,4,5,6,7,8,9), ivec3(10,50,90)) == imat3(10,2,3,4,50,6,7,8,90)); + } + SUBCASE("real") { STATIC_CHECK(real(qua{1,2,3,4}) == 4); STATIC_CHECK(real(qua{1,2,3,4}, 5) == qua{1,2,3,5}); diff --git a/untests/vmath_fix_tests.cpp b/untests/vmath_fix_tests.cpp index 5c89095..ab436f2 100644 --- a/untests/vmath_fix_tests.cpp +++ b/untests/vmath_fix_tests.cpp @@ -362,10 +362,10 @@ namespace vmath_hpp namespace vmath_hpp { template fix component(const fix2f&, std::size_t); - template fix2f component(fix2f, std::size_t, fix); + template fix2f component(const fix2f&, std::size_t, fix); template fix2f row(const fix2x2f&, std::size_t); - template fix2x2f row(fix2x2f, std::size_t, const fix2f&); + template fix2x2f row(const fix2x2f&, std::size_t, const fix2f&); template fix2f column(const fix2x2f&, std::size_t); template fix2x2f column(const fix2x2f&, std::size_t, const fix2f&);