simd constexpr vec: refactor to support constexpr for both operator[]s'

This commit is contained in:
sharkautarch 2024-10-05 13:10:44 -04:00
parent b21be860bf
commit c5c4b90be8
No known key found for this signature in database
GPG Key ID: F270CA9462164405
2 changed files with 21 additions and 40 deletions

View File

@ -19,6 +19,7 @@ namespace glm::detail
using data_t = typename detail::storage<4, T, detail::is_aligned<Q>::value>::type; using data_t = typename detail::storage<4, T, detail::is_aligned<Q>::value>::type;
union union
{ {
VecDataArray<4, T, Q> elementArr;
struct { struct {
union { T x, r, s; }; union { T x, r, s; };
union { T y, g, t; }; union { T y, g, t; };
@ -39,6 +40,8 @@ namespace glm::detail
using RowFour::q; using RowFour::q;
union union
{ {
static constexpr length_t data_len = (Q == aligned) ? 4 : 3;
VecDataArray<data_len, T, Q> elementArr;
struct { struct {
union { T x, r, s; }; union { T x, r, s; };
union { T y, g, t; }; union { T y, g, t; };
@ -59,6 +62,7 @@ namespace glm::detail
using RowFour::q; using RowFour::q;
union union
{ {
VecDataArray<2, T, Q> elementArr;
struct { struct {
union { T x, r, s; }; union { T x, r, s; };
union { T y, g, t; }; union { T y, g, t; };
@ -81,6 +85,7 @@ namespace glm::detail
using RowFour::q; using RowFour::q;
union union
{ {
VecDataArray<1, T, Q> elementArr;
struct { struct {
union { T x, r, s; }; union { T x, r, s; };
}; };

View File

@ -167,36 +167,12 @@ namespace glm
// -- Component Access -- // -- Component Access --
static constexpr length_t length(){ return L; } static constexpr length_t length(){ return L; }
inline T& operator[](length_t i) inline constexpr T& operator[](length_t i)
{ {
if (!std::is_constant_evaluated() && !__builtin_constant_p(i) ) { if (!std::is_constant_evaluated() && !__builtin_constant_p(i) ) {
GLM_ASSERT_LENGTH(i, L); GLM_ASSERT_LENGTH(i, L);
} }
switch (i) return a[i];
{
default:
__builtin_unreachable();
case 0:
return x;
case 1: {
if constexpr (L>=2)
return y;
else
__builtin_unreachable();
}
case 2:{
if constexpr (L>=3)
return z;
else
__builtin_unreachable();
}
case 3:{
if constexpr (L>=4)
return w;
else
__builtin_unreachable();
}
}
} }
inline constexpr T operator[](length_t i) const inline constexpr T operator[](length_t i) const
@ -205,7 +181,7 @@ namespace glm
GLM_ASSERT_LENGTH(i, L); GLM_ASSERT_LENGTH(i, L);
} }
return std::bit_cast<DataArray>(data).p[i]; return a[i];
} }
template <typename ScalarGetter> template <typename ScalarGetter>
@ -215,9 +191,9 @@ namespace glm
for (length_t i = 0; i < L; i++) { for (length_t i = 0; i < L; i++) {
a.p[i]=scalar(); a.p[i]=scalar();
} }
return std::bit_cast<data_t>(a); return a;
} else { } else {
return SimdHlp::simd_ctor_scalar(scalar()); return std::bit_cast<DataArray>(SimdHlp::simd_ctor_scalar(scalar()));
} }
} }
@ -233,9 +209,9 @@ namespace glm
a.p[i] = (T)ax.p[i]; a.p[i] = (T)ax.p[i];
} }
return std::bit_cast<data_t>(a); return a;
} else { } else {
return SimdHlp::simd_ctor(vecGetter()); return std::bit_cast<DataArray>(SimdHlp::simd_ctor(vecGetter()));
} }
} }
template <length_t len> template <length_t len>
@ -270,28 +246,28 @@ namespace glm
}; };
constexpr vec() = default; constexpr vec() = default;
constexpr vec(arithmetic auto scalar) : EC{.data= [scalar](){ auto s = [scalar](){ return scalar; }; return ctor_scalar(s); }() } {} constexpr vec(arithmetic auto scalar) : EC{.elementArr= [scalar](){ 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>)
constexpr vec(vec<Lx, Tx, Qx> v) : EC{.data= [d=std::bit_cast<VecDataArray<Lx, Tx, Qx>>(v.data)](){ auto s = [scalar=d.p[0]](){ return scalar; }; return ctor_scalar(s); }() } {} constexpr vec(vec<Lx, Tx, Qx> v) : EC{.elementArr= [d=std::bit_cast<VecDataArray<Lx, Tx, Qx>>(v.elementArr)](){ auto s = [scalar=d.p[0]](){ return scalar; }; return ctor_scalar(s); }() } {}
template <length_t Lx, typename Tx, qualifier Qx> requires (Lx != 1) template <length_t Lx, typename Tx, qualifier Qx> requires (Lx != 1)
constexpr vec(vec<Lx, Tx, Qx> v) : EC{.data= [v](){ auto vv = [v](){ return v; }; return ctor(vv); }() } {} constexpr vec(vec<Lx, Tx, Qx> v) : EC{.elementArr= [v](){ auto vv = [v](){ return v; }; return ctor(vv); }() } {}
constexpr vec(GccVec_t d) : EC{.data=std::bit_cast<data_t>(d)} {} constexpr vec(GccVec_t d) : EC{.elementArr=std::bit_cast<DataArray>(d)} {}
//template <length_t Lx, typename Tx, qualifier Qx> requires (Lx != 1) //template <length_t Lx, typename Tx, qualifier Qx> requires (Lx != 1)
//constexpr vec(__m128 d) : EC{ .data = std::bit_cast<detail::_data_t<L, T, Q>>(d) } {} //constexpr vec(__m128 d) : EC{ .data = std::bit_cast<detail::_data_t<L, T, Q>>(d) } {}
template <arithmetic... Scalar> requires (sizeof...(Scalar) == L) template <arithmetic... Scalar> requires (sizeof...(Scalar) == L)
constexpr vec(Scalar... scalar) constexpr vec(Scalar... scalar)
: EC : EC
{.data= [scalar...]() -> data_t {.elementArr= [scalar...]() -> elementArr
{ {
if (std::is_constant_evaluated() || (L == 3 && !BIsAlignedQ<Q>())) { if (std::is_constant_evaluated() || (L == 3 && !BIsAlignedQ<Q>())) {
DataArray a = {.p={ static_cast<T>(scalar)... }}; DataArray a = {.p={ static_cast<T>(scalar)... }};
return std::bit_cast<data_t>(a); return a;
} else { } else {
return SimdHlp::simd_ctor_multi_scalars(scalar...); return std::bit_cast<DataArray>(SimdHlp::simd_ctor_multi_scalars(scalar...));
} }
}() }()
} {} } {}
@ -299,7 +275,7 @@ namespace glm
template <typename VecOrScalar0, typename... VecOrScalar> requires (sizeof...(VecOrScalar) >= 1 && NotSameArithmeticTypes<VecOrScalar0, VecOrScalar...>()) template <typename VecOrScalar0, typename... VecOrScalar> requires (sizeof...(VecOrScalar) >= 1 && NotSameArithmeticTypes<VecOrScalar0, VecOrScalar...>())
constexpr vec(VecOrScalar0 const&__restrict__ vecOrScalar0, VecOrScalar... vecOrScalar) constexpr vec(VecOrScalar0 const&__restrict__ vecOrScalar0, VecOrScalar... vecOrScalar)
: EC : EC
{.data= [vecOrScalar0, vecOrScalar...]() -> data_t {.elementArr= [vecOrScalar0, vecOrScalar...]() -> elementArr
{ {
//type_vecx.inl never had any simd versions for ctor from mixes of scalars & vectors, //type_vecx.inl never had any simd versions for ctor from mixes of scalars & vectors,
//so I don't really need to figure out how I'd make a generic simd version for this ctor //so I don't really need to figure out how I'd make a generic simd version for this ctor
@ -328,7 +304,7 @@ namespace glm
} }
} }
return std::bit_cast<data_t>(destArr); return destArr;
}() }()
} {} } {}