added structured binding support for vector
This commit is contained in:
parent
a5d42995b2
commit
98685e49ed
2 changed files with 40 additions and 13 deletions
|
@ -26,6 +26,8 @@
|
||||||
#include <pw/core/globals.hpp>
|
#include <pw/core/globals.hpp>
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <concepts>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
namespace pw {
|
namespace pw {
|
||||||
|
|
||||||
|
@ -38,7 +40,7 @@ concept Vector3 = (N == 3);
|
||||||
template <typename T, auto N>
|
template <typename T, auto N>
|
||||||
concept Vector4 = (N == 4);
|
concept Vector4 = (N == 4);
|
||||||
|
|
||||||
template <typename Scalar, unsigned int N> struct vector final {
|
template <typename Scalar, std::size_t N> struct vector {
|
||||||
|
|
||||||
using value_type = Scalar;
|
using value_type = Scalar;
|
||||||
using size_type = decltype(N);
|
using size_type = decltype(N);
|
||||||
|
@ -56,7 +58,7 @@ template <typename Scalar, unsigned int N> struct vector final {
|
||||||
return std::forward<decltype(self)>(self).v_;
|
return std::forward<decltype(self)>(self).v_;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto&& operator[](this auto&& self, unsigned int e) {
|
auto&& operator[](this auto&& self, size_type e) {
|
||||||
return std::forward<decltype(self)>(self).v_[e];
|
return std::forward<decltype(self)>(self).v_[e];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +101,8 @@ template <typename Scalar, unsigned int N> struct vector final {
|
||||||
}(std::make_index_sequence<N>{});
|
}(std::make_index_sequence<N>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
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::size_t... Ss>(std::index_sequence<Ss...>) {
|
return [&]<std::size_t... Ss>(std::index_sequence<Ss...>) {
|
||||||
return vector<Scalar, N>{{A[Ss] + factor * (B[Ss] - A[Ss])...}};
|
return vector<Scalar, N>{{A[Ss] + factor * (B[Ss] - A[Ss])...}};
|
||||||
}(std::make_index_sequence<N>{});
|
}(std::make_index_sequence<N>{});
|
||||||
|
@ -183,9 +185,7 @@ template <typename Scalar, unsigned int N> struct vector final {
|
||||||
(*this)[0] * rhs[1] - rhs[0] * (*this)[1]};
|
(*this)[0] * rhs[1] - rhs[0] * (*this)[1]};
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr vector normalized() const noexcept {
|
constexpr vector normalized() const noexcept { return (*this) / norm(); }
|
||||||
return (*this) / norm();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto&& x(this auto&& self)
|
auto&& x(this auto&& self)
|
||||||
requires(Vector2<Scalar, N> || Vector3<Scalar, N> || Vector4<Scalar, N>)
|
requires(Vector2<Scalar, N> || Vector3<Scalar, N> || Vector4<Scalar, N>)
|
||||||
|
@ -254,15 +254,19 @@ template <typename Scalar, unsigned int N> struct vector final {
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// Iterators
|
// tuple like for structured bindings
|
||||||
//
|
//
|
||||||
constexpr const_pointer begin() const {
|
template <size_type idx> auto get(this auto&& self) -> decltype(auto) {
|
||||||
return &v_[0];
|
static_assert(idx < N, "out of bounds access to a member.");
|
||||||
|
return std::forward_like<decltype(self)>(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
|
// deduction guide for vector
|
||||||
|
@ -291,4 +295,16 @@ using vector4i = vector4<int>;
|
||||||
|
|
||||||
} // namespace pw
|
} // namespace pw
|
||||||
|
|
||||||
|
//
|
||||||
|
// tuple - protocol
|
||||||
|
//
|
||||||
|
template <class Scalar, std::size_t N>
|
||||||
|
struct std::tuple_size<pw::vector<Scalar, N>>
|
||||||
|
: std::integral_constant<std::size_t, N> {};
|
||||||
|
|
||||||
|
template <std::size_t I, class Scalar, std::size_t N>
|
||||||
|
struct std::tuple_element<I, pw::vector<Scalar, N>> {
|
||||||
|
using type = Scalar;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
#include <pw/core/vector.hpp>
|
#include <pw/core/vector.hpp>
|
||||||
|
|
||||||
#include <print>
|
#include <print>
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
auto main() -> int {
|
auto main() -> int {
|
||||||
|
|
||||||
|
@ -61,5 +64,13 @@ auto main() -> int {
|
||||||
std::print("{} * {} -> {}\n", pw::serialize::to_string(e1),
|
std::print("{} * {} -> {}\n", pw::serialize::to_string(e1),
|
||||||
pw::serialize::to_string(e2), e1_dot_e2);
|
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<decltype(vec3f)>);
|
||||||
|
|
||||||
|
auto& [x, y, z] = vec3f;
|
||||||
|
std::print("x:{} y:{} z:{}\n", x, y, z);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue