From f3365d0669534ac2b2c2d7f16ea65c0e531d0c12 Mon Sep 17 00:00:00 2001 From: Hartmut Seichter Date: Sun, 14 Jul 2024 23:16:14 +0200 Subject: [PATCH] added structured binding support for matrix --- src/core/include/pw/core/matrix.hpp | 30 ++++++++++++++++++++++++--- src/core/include/pw/core/vector.hpp | 16 +++++++------- src/core/tests/pwcore_test_matrix.cpp | 8 +++++++ src/core/tests/pwcore_test_vector.cpp | 1 - 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/core/include/pw/core/matrix.hpp b/src/core/include/pw/core/matrix.hpp index 5199228..0a305e2 100644 --- a/src/core/include/pw/core/matrix.hpp +++ b/src/core/include/pw/core/matrix.hpp @@ -23,28 +23,32 @@ #ifndef PW_CORE_MATRIX_HPP #define PW_CORE_MATRIX_HPP +#include #include #include #include +#include #include namespace pw { -template +template struct matrix final { - static_assert(Rows > 0 && Cols > 0, "undefined matrix type"); + static_assert(Rows > 0 && Cols > 0, "Undefined matrix type."); static constexpr unsigned int diag_size{std::min(Rows, Cols)}; static constexpr unsigned int rows{Rows}; static constexpr unsigned int cols{Cols}; static constexpr bool is_square{Rows == Cols}; + using size_type = std::common_type_t; + using row_type = vector; + using column_type = vector; using diag_type = vector; using transpose_type = matrix; using minor_type = matrix; - using column_type = vector; vector, Rows> m_{}; @@ -56,6 +60,14 @@ struct matrix final { return std::forward(self).m_[r]; } + // + // part of tuple-protocol + // + template auto get(this auto&& self) -> decltype(auto) { + static_assert(idx < Rows, "Out of bounds access to a member."); + return std::forward_like(self.m_[idx]); + } + constexpr auto diagonal() const noexcept -> diag_type { return [this](std::index_sequence) { return diag_type{(*this)[Is][Is]...}; @@ -226,4 +238,16 @@ constexpr auto operator*(const matrix& A, } // namespace pw +// +// tuple - protocol +// +template +struct std::tuple_size> + : std::integral_constant {}; + +template +struct std::tuple_element> { + using type = pw::matrix::row_type; +}; + #endif diff --git a/src/core/include/pw/core/vector.hpp b/src/core/include/pw/core/vector.hpp index bf589d9..0008c25 100644 --- a/src/core/include/pw/core/vector.hpp +++ b/src/core/include/pw/core/vector.hpp @@ -40,7 +40,9 @@ concept Vector3 = (N == 3); template concept Vector4 = (N == 4); -template struct vector { +template struct vector final { + + static_assert(N > 0, "Undefined vector space."); using value_type = Scalar; using size_type = decltype(N); @@ -71,7 +73,7 @@ template struct vector { template static constexpr auto make(Args&&... values) noexcept -> vector { - static_assert(sizeof...(Args) == N, "incorrect number of arguments"); + static_assert(sizeof...(Args) == N, "Incorrect number of arguments."); return {{Scalar(values)...}}; } @@ -84,7 +86,7 @@ template struct vector { template constexpr auto swizzle(Args&&... indices) const noexcept -> vector { - return {{Scalar(v_[indices])...}}; + return {{Scalar{v_[indices]}...}}; } constexpr auto minor(std::unsigned_integral auto d0) const noexcept { @@ -102,9 +104,9 @@ template struct vector { } static constexpr auto lerp(const vector& A, const vector& B, - const Scalar& factor) -> vector { + const Scalar& t) -> vector { return [&](std::index_sequence) { - return vector{{A[Ss] + factor * (B[Ss] - A[Ss])...}}; + return vector{{A[Ss] + t * (B[Ss] - A[Ss])...}}; }(std::make_index_sequence{}); } @@ -254,10 +256,10 @@ template struct vector { }; // - // tuple like for structured bindings + // part of tuple-protocol // template auto get(this auto&& self) -> decltype(auto) { - static_assert(idx < N, "out of bounds access to a member."); + static_assert(idx < N, "Out of bounds access to a member."); return std::forward_like(self.v_[idx]); } diff --git a/src/core/tests/pwcore_test_matrix.cpp b/src/core/tests/pwcore_test_matrix.cpp index 594142d..a63e4f7 100644 --- a/src/core/tests/pwcore_test_matrix.cpp +++ b/src/core/tests/pwcore_test_matrix.cpp @@ -3,6 +3,8 @@ #include #include +#include + auto main() -> int { pw::debug::d() << "pixwerx.matrix.test\n"; @@ -38,4 +40,10 @@ auto main() -> int { auto m22_tp_col1 = m22_tp.column(1); pw::debug::d() << "matrix<2,2>{1,2,3,4}.transposed().column(1) -> \n" << pw::serialize::to_string(m22_tp_col1); + + auto& [r1, r2] = m22_inv; + + auto& [r1_x, r1_y] = r1; + + std::print("r1.x:{} r1.y:{}\n", r1_x, r1_y); } diff --git a/src/core/tests/pwcore_test_vector.cpp b/src/core/tests/pwcore_test_vector.cpp index 697038e..446671d 100644 --- a/src/core/tests/pwcore_test_vector.cpp +++ b/src/core/tests/pwcore_test_vector.cpp @@ -6,7 +6,6 @@ #include #include - auto main() -> int { auto v2_A = pw::vector{3.2, 1.2};