diff --git a/src/core/include/pw/core/vector.hpp b/src/core/include/pw/core/vector.hpp index 4a1099e..bf589d9 100644 --- a/src/core/include/pw/core/vector.hpp +++ b/src/core/include/pw/core/vector.hpp @@ -26,6 +26,8 @@ #include #include +#include +#include namespace pw { @@ -38,7 +40,7 @@ concept Vector3 = (N == 3); template concept Vector4 = (N == 4); -template struct vector final { +template struct vector { using value_type = Scalar; using size_type = decltype(N); @@ -56,7 +58,7 @@ template struct vector final { return std::forward(self).v_; } - auto&& operator[](this auto&& self, unsigned int e) { + auto&& operator[](this auto&& self, size_type e) { return std::forward(self).v_[e]; } @@ -99,8 +101,8 @@ template struct vector final { }(std::make_index_sequence{}); } - static constexpr auto lerp(const vector& A, const vector& B,const Scalar& factor) -> vector - { + static constexpr auto lerp(const vector& A, const vector& B, + const Scalar& factor) -> vector { return [&](std::index_sequence) { return vector{{A[Ss] + factor * (B[Ss] - A[Ss])...}}; }(std::make_index_sequence{}); @@ -183,9 +185,7 @@ template struct vector final { (*this)[0] * rhs[1] - rhs[0] * (*this)[1]}; } - constexpr vector normalized() const noexcept { - return (*this) / norm(); - } + constexpr vector normalized() const noexcept { return (*this) / norm(); } auto&& x(this auto&& self) requires(Vector2 || Vector3 || Vector4) @@ -254,15 +254,19 @@ template struct vector final { }; // - // Iterators + // tuple like for structured bindings // - constexpr const_pointer begin() const { - return &v_[0]; + template auto get(this auto&& self) -> decltype(auto) { + static_assert(idx < N, "out of bounds access to a member."); + return std::forward_like(self.v_[idx]); } - constexpr const_pointer end() const { - return &v_[N]; - } + // + // Iterators + // + constexpr const_pointer begin() const { return &v_[0]; } + + constexpr const_pointer end() const { return &v_[N]; } }; // deduction guide for vector @@ -291,4 +295,16 @@ using vector4i = vector4; } // namespace pw +// +// tuple - protocol +// +template +struct std::tuple_size> + : std::integral_constant {}; + +template +struct std::tuple_element> { + using type = Scalar; +}; + #endif diff --git a/src/core/tests/pwcore_test_vector.cpp b/src/core/tests/pwcore_test_vector.cpp index 84d0810..697038e 100644 --- a/src/core/tests/pwcore_test_vector.cpp +++ b/src/core/tests/pwcore_test_vector.cpp @@ -3,6 +3,9 @@ #include #include +#include +#include + auto main() -> int { @@ -61,5 +64,13 @@ auto main() -> int { std::print("{} * {} -> {}\n", pw::serialize::to_string(e1), pw::serialize::to_string(e2), e1_dot_e2); + auto vec3f = pw::vector{1.f, 2.f, 3.f}; + + std::print("y: {}\n", vec3f.get<1>()); + std::print("tuple size {}\n", std::tuple_size_v); + + auto& [x, y, z] = vec3f; + std::print("x:{} y:{} z:{}\n", x, y, z); + return 0; }