simd constexpr vec: fix compiler error on clang

This commit is contained in:
sharkautarch 2024-09-13 22:55:52 -04:00
parent 012df5e3cc
commit da8fe302de
No known key found for this signature in database
GPG Key ID: F270CA9462164405
2 changed files with 101 additions and 79 deletions

View File

@ -2,6 +2,16 @@
namespace glm::detail 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; }
struct Empty {};
struct RowTwo {
[[no_unique_address]] Empty y; [[no_unique_address]] Empty g; [[no_unique_address]] Empty t;
};
struct RowThree {
[[no_unique_address]] Empty z; [[no_unique_address]] Empty b; [[no_unique_address]] Empty p;
};
struct RowFour {
[[no_unique_address]] Empty w; [[no_unique_address]] Empty a; [[no_unique_address]] Empty q;
};
template <qualifier Q, typename T, length_t L> template <qualifier Q, typename T, length_t L>
struct ElementCollection; struct ElementCollection;
template <qualifier Q, typename T> template <qualifier Q, typename T>
@ -21,9 +31,11 @@ namespace glm::detail
template <qualifier Q, typename T> template <qualifier Q, typename T>
struct ElementCollection<Q, T, 3> { struct ElementCollection<Q, T, 3> : RowFour {
using data_t = typename detail::storage<3, T, detail::is_aligned<Q>::value>::type; using data_t = typename detail::storage<3, T, detail::is_aligned<Q>::value>::type;
struct w {}; struct a {}; struct q{}; using RowFour::w;
using RowFour::a;
using RowFour::q;
union union
{ {
struct { struct {
@ -35,10 +47,14 @@ namespace glm::detail
}; };
}; };
template <qualifier Q, typename T> template <qualifier Q, typename T>
struct ElementCollection<Q, T, 2> { struct ElementCollection<Q, T, 2> : RowThree, RowFour {
using data_t = typename detail::storage<2, T, detail::is_aligned<Q>::value>::type; using data_t = typename detail::storage<2, T, detail::is_aligned<Q>::value>::type;
struct z {}; struct b {}; struct p{}; using RowThree::z;
struct w {}; struct a {}; struct q{}; using RowThree::b;
using RowThree::p;
using RowFour::w;
using RowFour::a;
using RowFour::q;
union union
{ {
struct { struct {
@ -49,11 +65,17 @@ namespace glm::detail
}; };
}; };
template <qualifier Q, typename T> template <qualifier Q, typename T>
struct ElementCollection<Q, T, 1> { struct ElementCollection<Q, T, 1> : RowTwo, RowThree, RowFour {
using data_t = typename detail::storage<1, T, detail::is_aligned<Q>::value>::type; using data_t = typename detail::storage<1, T, detail::is_aligned<Q>::value>::type;
struct y {}; struct g {}; struct t{}; using RowTwo::y;
struct z {}; struct b {}; struct p{}; using RowTwo::g;
struct w {}; struct a {}; struct q{}; using RowTwo::t;
using RowThree::z;
using RowThree::b;
using RowThree::p;
using RowFour::w;
using RowFour::a;
using RowFour::q;
union union
{ {
struct { struct {

View File

@ -121,18 +121,18 @@ namespace glm
struct vec : detail::ElementCollection<Q, T, L> struct vec : detail::ElementCollection<Q, T, L>
{ {
// -- Data -- // -- Data --
using EC<L, T, Q>::x; using detail::ElementCollection<Q, T, L>::x;
using EC<L, T, Q>::y; using detail::ElementCollection<Q, T, L>::y;
using EC<L, T, Q>::z; using detail::ElementCollection<Q, T, L>::z;
using EC<L, T, Q>::w; using detail::ElementCollection<Q, T, L>::w;
using EC<L, T, Q>::r; using detail::ElementCollection<Q, T, L>::r;
using EC<L, T, Q>::g; using detail::ElementCollection<Q, T, L>::g;
using EC<L, T, Q>::b; using detail::ElementCollection<Q, T, L>::b;
using EC<L, T, Q>::a; using detail::ElementCollection<Q, T, L>::a;
using EC<L, T, Q>::s; using detail::ElementCollection<Q, T, L>::s;
using EC<L, T, Q>::t; using detail::ElementCollection<Q, T, L>::t;
using EC<L, T, Q>::p; using detail::ElementCollection<Q, T, L>::p;
using EC<L, T, Q>::q; using detail::ElementCollection<Q, T, L>::q;
using SimdHlp = detail::SimdHelpers<L, T, Q>; using SimdHlp = detail::SimdHelpers<L, T, Q>;
using DataArray = VecDataArray<L, T, Q>; using DataArray = VecDataArray<L, T, Q>;
@ -596,7 +596,7 @@ namespace glm
} }
template<typename Tx> template<typename Tx>
inline GLM_CONSTEXPR vec<L, T, Q> & operator|=(vec<1, Tx, Q> const& v) requires (NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> & operator|=(vec<1, Tx, Q> v) requires (NotVec1<L>)
{ {
if constexpr (L < 3) { if constexpr (L < 3) {
this->data |= v.data; this->data |= v.data;
@ -606,7 +606,7 @@ namespace glm
} }
template<typename Tx> template<typename Tx>
inline GLM_CONSTEXPR vec<L, T, Q> & operator|=(vec<L, Tx, Q> const& v) inline GLM_CONSTEXPR vec<L, T, Q> & operator|=(vec<L, Tx, Q> v)
{ {
if constexpr (L < 3) { if constexpr (L < 3) {
this->data |= v.data; this->data |= v.data;
@ -625,7 +625,7 @@ namespace glm
} }
template<typename Tx> template<typename Tx>
inline GLM_CONSTEXPR vec<L, T, Q> & operator^=(vec<1, Tx, Q> const& v) requires (NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> & operator^=(vec<1, Tx, Q> v) requires (NotVec1<L>)
{ {
if constexpr (L < 3) { if constexpr (L < 3) {
this->data ^= v.data; this->data ^= v.data;
@ -635,7 +635,7 @@ namespace glm
} }
template<typename Tx> template<typename Tx>
inline GLM_CONSTEXPR vec<L, T, Q> & operator^=(vec<L, Tx, Q> const& v) inline GLM_CONSTEXPR vec<L, T, Q> & operator^=(vec<L, Tx, Q> v)
{ {
return (*this = detail::compute_vec_xor<L, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<L, T, Q>(v))); return (*this = detail::compute_vec_xor<L, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(*this, vec<L, T, Q>(v)));
} }
@ -650,7 +650,7 @@ namespace glm
} }
template<typename Tx> template<typename Tx>
inline GLM_CONSTEXPR vec<L, T, Q> & operator<<=(vec<1, Tx, Q> const& v) requires (NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> & operator<<=(vec<1, Tx, Q> v) requires (NotVec1<L>)
{ {
if constexpr (L < 3) { if constexpr (L < 3) {
this->data <<= v.data; this->data <<= v.data;
@ -660,7 +660,7 @@ namespace glm
} }
template<typename Tx> template<typename Tx>
inline GLM_CONSTEXPR vec<L, T, Q> & operator<<=(vec<L, Tx, Q> const& v) inline GLM_CONSTEXPR vec<L, T, Q> & operator<<=(vec<L, Tx, Q> v)
{ {
if constexpr (L < 3) { if constexpr (L < 3) {
this->data <<= v.data; this->data <<= v.data;
@ -679,7 +679,7 @@ namespace glm
} }
template<typename Tx> template<typename Tx>
inline GLM_CONSTEXPR vec<L, T, Q> & operator>>=(vec<1, Tx, Q> const& v) requires (NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> & operator>>=(vec<1, Tx, Q> v) requires (NotVec1<L>)
{ {
if constexpr (L < 3) { if constexpr (L < 3) {
this->data >>= v.data; this->data >>= v.data;
@ -689,7 +689,7 @@ namespace glm
} }
template<typename Tx> template<typename Tx>
inline GLM_CONSTEXPR vec<L, T, Q> & operator>>=(vec<L, Tx, Q> const& v) inline GLM_CONSTEXPR vec<L, T, Q> & operator>>=(vec<L, Tx, Q> v)
{ {
if constexpr (L < 3) { if constexpr (L < 3) {
this->data >>= v.data; this->data >>= v.data;
@ -718,17 +718,17 @@ namespace glm
} }
template <length_t Lx> template <length_t Lx>
inline GLM_CONSTEXPR vec<L, T, Q> operator+(vec<Lx, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator+(vec<Lx, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(*this) += v2; return vec<L, T, Q>(*this) += v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator+(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator+(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(v) += scalar; return vec<L, T, Q>(v) += scalar;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator+(vec<1, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator+(vec<1, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v2) += v1; return vec<L, T, Q>(v2) += v1;
} }
@ -744,22 +744,22 @@ namespace glm
} }
template <length_t Lx> template <length_t Lx>
inline GLM_CONSTEXPR vec<L, T, Q> operator-(vec<Lx, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator-(vec<Lx, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(*this) -= v2; return vec<L, T, Q>(*this) -= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator-(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator-(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(scalar) -= v; return vec<L, T, Q>(scalar) -= v;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator-(vec<1, T, Q> const& v1, vec<L, T, Q> const& v2) requires (NotVec1<L>) friend inline GLM_CONSTEXPR vec<L, T, Q> operator-(vec<1, T, Q> v1, vec<L, T, Q> v2) requires (NotVec1<L>)
{ {
return vec<L, T, Q>(v1.x) -= v2; return vec<L, T, Q>(v1.x) -= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator-(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator-(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v1) -= v2; return vec<L, T, Q>(v1) -= v2;
} }
@ -770,25 +770,25 @@ namespace glm
} }
template <length_t Lx> template <length_t Lx>
inline GLM_CONSTEXPR vec<L, T, Q> operator*(vec<Lx, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator*(vec<Lx, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(*this) *= v2; return vec<L, T, Q>(*this) *= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator*(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator*(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(v) *= scalar; return vec<L, T, Q>(v) *= scalar;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator*(vec<1, T, Q> const& v1, vec<L, T, Q> const& v2) requires (NotVec1<L>) friend inline GLM_CONSTEXPR vec<L, T, Q> operator*(vec<1, T, Q> v1, vec<L, T, Q> v2) requires (NotVec1<L>)
{ {
return vec<L, T, Q>(v2) *= v1; return vec<L, T, Q>(v2) *= v1;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator*(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator*(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v1) *= v2; return vec<L, T, Q>(v1) *= v2;
} }
@ -801,25 +801,25 @@ namespace glm
template <length_t Lx> template <length_t Lx>
inline GLM_CONSTEXPR vec<L, T, Q> operator/(vec<Lx, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator/(vec<Lx, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(*this) /= v2; return vec<L, T, Q>(*this) /= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator/(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator/(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(scalar) /= v; return vec<L, T, Q>(scalar) /= v;
} }
template <length_t Lx> template <length_t Lx>
friend inline GLM_CONSTEXPR vec<L, T, Q> operator/(vec<Lx, T, Q> const& v1, vec<L, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) friend inline GLM_CONSTEXPR vec<L, T, Q> operator/(vec<Lx, T, Q> v1, vec<L, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(v1.x) /= v2; return vec<L, T, Q>(v1.x) /= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator/(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator/(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v1) /= v2; return vec<L, T, Q>(v1) /= v2;
} }
@ -827,212 +827,212 @@ namespace glm
// -- Binary bit operators -- // -- Binary bit operators --
friend inline GLM_CONSTEXPR vec<L, T, Q> operator%(vec<L, T, Q> const& v, T scalar) friend inline GLM_CONSTEXPR vec<L, T, Q> operator%(vec<L, T, Q> v, T scalar)
{ {
return vec<L, T, Q>(v) %= scalar; return vec<L, T, Q>(v) %= scalar;
} }
template <length_t Lx> template <length_t Lx>
inline GLM_CONSTEXPR vec<L, T, Q> operator%(vec<Lx, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator%(vec<Lx, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(*this) %= v2.x; return vec<L, T, Q>(*this) %= v2.x;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator%(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator%(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(scalar) %= v; return vec<L, T, Q>(scalar) %= v;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator%(vec<1, T, Q> const& scalar, vec<L, T, Q> const& v) requires (NotVec1<L>) friend inline GLM_CONSTEXPR vec<L, T, Q> operator%(vec<1, T, Q> scalar, vec<L, T, Q> v) requires (NotVec1<L>)
{ {
return vec<L, T, Q>(scalar.x) %= v; return vec<L, T, Q>(scalar.x) %= v;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator%(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator%(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v1) %= v2; return vec<L, T, Q>(v1) %= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator&(vec<L, T, Q> const& v, T scalar) friend inline GLM_CONSTEXPR vec<L, T, Q> operator&(vec<L, T, Q> v, T scalar)
{ {
return vec<L, T, Q>(v) &= scalar; return vec<L, T, Q>(v) &= scalar;
} }
inline GLM_CONSTEXPR vec<L, T, Q> operator&(vec<1, T, Q> const& scalar) requires (NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator&(vec<1, T, Q> scalar) requires (NotVec1<L>)
{ {
return vec<L, T, Q>(*this) &= scalar; return vec<L, T, Q>(*this) &= scalar;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator&(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator&(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(scalar) &= v; return vec<L, T, Q>(scalar) &= v;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator&(vec<1, T, Q> const& v1, vec<L, T, Q> const& v2) requires (NotVec1<L>) friend inline GLM_CONSTEXPR vec<L, T, Q> operator&(vec<1, T, Q> v1, vec<L, T, Q> v2) requires (NotVec1<L>)
{ {
return vec<L, T, Q>(v1.x) &= v2; return vec<L, T, Q>(v1.x) &= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator&(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator&(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v1) &= v2; return vec<L, T, Q>(v1) &= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator|(vec<L, T, Q> const& v, T scalar) friend inline GLM_CONSTEXPR vec<L, T, Q> operator|(vec<L, T, Q> v, T scalar)
{ {
return vec<L, T, Q>(v) |= scalar; return vec<L, T, Q>(v) |= scalar;
} }
template <length_t Lx> template <length_t Lx>
inline GLM_CONSTEXPR vec<L, T, Q> operator|(vec<Lx, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator|(vec<Lx, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(*this) |= v2.x; return vec<L, T, Q>(*this) |= v2.x;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator|(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator|(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(scalar) |= v; return vec<L, T, Q>(scalar) |= v;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator|(vec<1, T, Q> const& v1, vec<L, T, Q> const& v2) requires (NotVec1<L>) friend inline GLM_CONSTEXPR vec<L, T, Q> operator|(vec<1, T, Q> v1, vec<L, T, Q> v2) requires (NotVec1<L>)
{ {
return vec<L, T, Q>(v1.x) |= v2; return vec<L, T, Q>(v1.x) |= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator|(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator|(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v1) |= v2; return vec<L, T, Q>(v1) |= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator^(vec<L, T, Q> const& v, T scalar) friend inline GLM_CONSTEXPR vec<L, T, Q> operator^(vec<L, T, Q> v, T scalar)
{ {
return vec<L, T, Q>(v) ^= scalar; return vec<L, T, Q>(v) ^= scalar;
} }
template <length_t Lx> template <length_t Lx>
inline GLM_CONSTEXPR vec<L, T, Q> operator^(vec<Lx, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator^(vec<Lx, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(*this) ^= v2.x; return vec<L, T, Q>(*this) ^= v2.x;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator^(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator^(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(scalar) ^= v; return vec<L, T, Q>(scalar) ^= v;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator^(vec<1, T, Q> const& v1, vec<L, T, Q> const& v2) requires (NotVec1<L>) friend inline GLM_CONSTEXPR vec<L, T, Q> operator^(vec<1, T, Q> v1, vec<L, T, Q> v2) requires (NotVec1<L>)
{ {
return vec<L, T, Q>(v1.x) ^= v2; return vec<L, T, Q>(v1.x) ^= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator^(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator^(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v1) ^= v2; return vec<L, T, Q>(v1) ^= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator<<(vec<L, T, Q> const& v, T scalar) friend inline GLM_CONSTEXPR vec<L, T, Q> operator<<(vec<L, T, Q> v, T scalar)
{ {
return vec<L, T, Q>(v) <<= scalar; return vec<L, T, Q>(v) <<= scalar;
} }
template <length_t Lx> template <length_t Lx>
inline GLM_CONSTEXPR vec<L, T, Q> operator<<(vec<Lx, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator<<(vec<Lx, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(*this) <<= v2.x; return vec<L, T, Q>(*this) <<= v2.x;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator<<(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator<<(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(scalar) <<= v; return vec<L, T, Q>(scalar) <<= v;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator<<(vec<1, T, Q> const& v1, vec<L, T, Q> const& v2) requires (NotVec1<L>) friend inline GLM_CONSTEXPR vec<L, T, Q> operator<<(vec<1, T, Q> v1, vec<L, T, Q> v2) requires (NotVec1<L>)
{ {
return vec<L, T, Q>(v1.x) <<= v2; return vec<L, T, Q>(v1.x) <<= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator<<(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator<<(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v1) <<= v2; return vec<L, T, Q>(v1) <<= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator>>(vec<L, T, Q> const& v, T scalar) friend inline GLM_CONSTEXPR vec<L, T, Q> operator>>(vec<L, T, Q> v, T scalar)
{ {
return vec<L, T, Q>(v) >>= scalar; return vec<L, T, Q>(v) >>= scalar;
} }
template <length_t Lx> template <length_t Lx>
inline GLM_CONSTEXPR vec<L, T, Q> operator>>(vec<Lx, T, Q> const& v2) requires (!NotVec1<Lx> && NotVec1<L>) inline GLM_CONSTEXPR vec<L, T, Q> operator>>(vec<Lx, T, Q> v2) requires (!NotVec1<Lx> && NotVec1<L>)
{ {
return vec<L, T, Q>(*this) >>= v2.x; return vec<L, T, Q>(*this) >>= v2.x;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator>>(T scalar, vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator>>(T scalar, vec<L, T, Q> v)
{ {
return vec<L, T, Q>(scalar) >>= v; return vec<L, T, Q>(scalar) >>= v;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator>>(vec<1, T, Q> const& v1, vec<L, T, Q> const& v2) requires (NotVec1<L>) friend inline GLM_CONSTEXPR vec<L, T, Q> operator>>(vec<1, T, Q> v1, vec<L, T, Q> v2) requires (NotVec1<L>)
{ {
return vec<L, T, Q>(v1.x) >>= v2; return vec<L, T, Q>(v1.x) >>= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator>>(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR vec<L, T, Q> operator>>(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return vec<L, T, Q>(v1) >>= v2; return vec<L, T, Q>(v1) >>= v2;
} }
friend inline GLM_CONSTEXPR vec<L, T, Q> operator~(vec<L, T, Q> const& v) friend inline GLM_CONSTEXPR vec<L, T, Q> operator~(vec<L, T, Q> v)
{ {
return detail::compute_vec_bitwise_not<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v); return detail::compute_vec_bitwise_not<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v);
} }
// -- Boolean operators -- // -- Boolean operators --
friend inline GLM_CONSTEXPR bool operator==(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR bool operator==(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return detail::compute_vec_equal<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2); return detail::compute_vec_equal<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2);
} }
friend inline GLM_CONSTEXPR bool operator!=(vec<L, T, Q> const& v1, vec<L, T, Q> const& v2) friend inline GLM_CONSTEXPR bool operator!=(vec<L, T, Q> v1, vec<L, T, Q> v2)
{ {
return detail::compute_vec_nequal<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2); return detail::compute_vec_nequal<4, T, Q, detail::is_int<T>::value, sizeof(T) * 8, detail::is_aligned<Q>::value>::call(v1, v2);
} }
}; };
template <length_t Lx, typename Tx, qualifier Qx> requires (std::is_same_v<Tx, bool>) template <length_t Lx, typename Tx, qualifier Qx> requires (std::is_same_v<Tx, bool>)
inline GLM_CONSTEXPR vec<Lx, bool, Qx> operator&&(vec<Lx, Tx, Qx> const& v1, vec<Lx, Tx, Qx> const& v2) inline GLM_CONSTEXPR vec<Lx, bool, Qx> operator&&(vec<Lx, Tx, Qx> v1, vec<Lx, Tx, Qx> v2)
{ {
return vec<Lx, bool, Qx>(v1.x && v2.x, v1.y && v2.y, v1.z && v2.z, v1.w && v2.w); return vec<Lx, bool, Qx>(v1.x && v2.x, v1.y && v2.y, v1.z && v2.z, v1.w && v2.w);
} }
template <length_t Lx, typename Tx, qualifier Qx> requires (std::is_same_v<Tx, bool>) template <length_t Lx, typename Tx, qualifier Qx> requires (std::is_same_v<Tx, bool>)
inline GLM_CONSTEXPR vec<Lx, bool, Qx> operator||(vec<Lx, bool, Qx> const& v1, vec<Lx, bool, Qx> const& v2) inline GLM_CONSTEXPR vec<Lx, bool, Qx> operator||(vec<Lx, bool, Qx> v1, vec<Lx, bool, Qx> v2)
{ {
return vec<Lx, bool, Qx>(v1.x || v2.x, v1.y || v2.y, v1.z || v2.z, v1.w || v2.w); return vec<Lx, bool, Qx>(v1.x || v2.x, v1.y || v2.y, v1.z || v2.z, v1.w || v2.w);
} }