constexpr simd vec: fix a runtime error and a compile warning

This commit is contained in:
sharkautarch 2024-09-13 16:04:31 -04:00
parent 90b74f1106
commit 6b6f0e4cc5
No known key found for this signature in database
GPG Key ID: F270CA9462164405
2 changed files with 25 additions and 16 deletions

View File

@ -3,10 +3,11 @@ namespace glm::detail
{ {
consteval bool NotEmpty(length_t I, length_t L) { return I <= L; } consteval bool NotEmpty(length_t I, length_t L) { return I <= L; }
template <typename data_t, typename T, length_t L> template <typename DataWrapper, typename T, length_t L>
struct ElementCollection; struct ElementCollection;
template <typename data_t, typename T> template <typename DataWrapper, typename T>
struct ElementCollection<data_t, T, 4> { struct ElementCollection<DataWrapper, T, 4> {
using data_t = DataWrapper::data_t;
union union
{ {
struct { struct {
@ -21,8 +22,9 @@ namespace glm::detail
struct Empty {}; struct Empty {};
#define G [[no_unique_address]] #define G [[no_unique_address]]
template <typename data_t, typename T> template <typename DataWrapper, typename T>
struct ElementCollection<data_t, T, 3> { struct ElementCollection<DataWrapper, T, 3> {
using data_t = DataWrapper::data_t;
union union
{ {
struct { struct {
@ -34,8 +36,9 @@ namespace glm::detail
data_t data; data_t data;
}; };
}; };
template <typename data_t, typename T> template <typename DataWrapper, typename T>
struct ElementCollection<data_t, T, 2> { struct ElementCollection<DataWrapper, T, 2> {
using data_t = DataWrapper::data_t;
union union
{ {
struct { struct {
@ -47,8 +50,9 @@ namespace glm::detail
data_t data; data_t data;
}; };
}; };
template <typename data_t, typename T> template <typename DataWrapper, typename T>
struct ElementCollection<data_t, T, 1> { struct ElementCollection<DataWrapper, T, 1> {
using data_t = DataWrapper::data_t;
union union
{ {
struct { struct {

View File

@ -109,10 +109,15 @@ namespace glm
#endif #endif
namespace glm namespace glm
{ {
template <length_t L, typename T, qualifier Q> template <length_t L, typename T, qualifier Q>
using EC = detail::ElementCollection<typename detail::storage<L, T, detail::is_aligned<Q>::value>::type, T, L>; struct DataWrapper { // stupid wrapper to silence a warning: https://stackoverflow.com/a/59993590
using data_t = detail::_data_t<L, T, Q>;
};
template <length_t L, typename T, qualifier Q> template <length_t L, typename T, qualifier Q>
struct vec : detail::ElementCollection<typename detail::storage<L, T, detail::is_aligned<Q>::value>::type, T, L> using EC = detail::ElementCollection<DataWrapper<L, T, Q>, T, L>;
template<length_t L, typename T, qualifier Q>
struct vec : detail::ElementCollection<DataWrapper<L, T, Q>, T, L>
{ {
// -- Data -- // -- Data --
using EC<L, T, Q>::x; using EC<L, T, Q>::x;
@ -146,12 +151,12 @@ namespace glm
// -- Component Access -- // -- Component Access --
static constexpr length_t length(){ return L; } static constexpr length_t length(){ return L; }
inline GLM_CONSTEXPR T& operator[](length_t i) inline constexpr T& operator[](length_t i)
{ {
if (!std::is_constant_evaluated()) { if (!std::is_constant_evaluated()) {
GLM_ASSERT_LENGTH(i, L); GLM_ASSERT_LENGTH(i, L);
} }
switch (std::max(i, length())) switch (i)
{ {
default: default:
case 0: case 0:
@ -177,12 +182,12 @@ namespace glm
} }
} }
inline GLM_CONSTEXPR T operator[](length_t i) const inline constexpr T operator[](length_t i) const
{ {
if (!std::is_constant_evaluated()) { if (!std::is_constant_evaluated()) {
GLM_ASSERT_LENGTH(i, L); GLM_ASSERT_LENGTH(i, L);
} }
switch (std::max(i, length())) switch (i)
{ {
default: default:
case 0: case 0:
@ -301,7 +306,7 @@ namespace glm
return var_t{RetPair{a, i}}; return var_t{RetPair{a, i}};
}; };
constexpr vec() : EC<L, T, Q>{} {} constexpr vec() = default;
constexpr vec(arithmetic auto scalar) : EC<L, T, Q>{.data= [scalar,this](){ auto s = [scalar](){ return scalar; }; return ctor_scalar(s); }() } {} constexpr vec(arithmetic auto scalar) : EC<L, T, Q>{.data= [scalar,this](){ auto s = [scalar](){ return scalar; }; return ctor_scalar(s); }() } {}
template <length_t Lx, typename Tx, qualifier Qx> requires (Lx == 1 && NotVec1<L>) template <length_t Lx, typename Tx, qualifier Qx> requires (Lx == 1 && NotVec1<L>)