10#define TEST_VEC_TRAITS(VecType) \
11 static_assert(sizeof(VecType) == sizeof(VecType::ITEM_TYPE) * VecType::ITEM_COUNT, \
12 #VecType " size mismatch! Possible unexpected padding."); \
13 static_assert(std::is_standard_layout_v<VecType>, \
14 #VecType " is not Standard Layout. This breaks C-compatibility/offsetof."); \
16 static_assert(std::is_trivially_copyable_v<VecType>, \
17 #VecType " is not trivially copyable. This hurts pass-by-value performance."); \
18 static_assert(std::is_trivially_destructible_v<VecType>, \
19 #VecType " has a non-trivial destructor. This prevents it from being in a union."); \
21 static_assert(alignof(VecType) >= alignof(VecType::ITEM_TYPE), \
22 #VecType " alignment is weaker than its scalar component."); \
24 static_assert(std::is_default_constructible_v<VecType>, \
25 #VecType " should be default constructible for array allocations."); \
26 static_assert(std::is_trivially_copy_constructible_v<VecType>, \
27 #VecType " copy constructor is not trivial."); \
28 static_assert(std::is_trivially_move_constructible_v<VecType>, \
29 #VecType " move constructor is not trivial (math types should be POD-like).");
33 template<
typename _T,
size_t _N>
88 template <
typename _T,
size_t _N>
93 static constexpr size_t ITEM_COUNT = _N;
98 for (
int i = 0; i < ITEM_COUNT; ++i)
100 this->data[i] = scalar;
104 template <
typename... Args>
109 ((this->data[i++] = args), ...);
115 static constexpr vec NaN() {
return vec(std::numeric_limits<ITEM_TYPE>::quiet_NaN()); }
119 for (
size_t i = 0; i < ITEM_COUNT; ++i)
121 (*this)[i] += rhs[i];
128 for (
size_t i = 0; i < ITEM_COUNT; ++i)
130 (*this)[i] -= rhs[i];
137 for (
size_t i = 0; i < ITEM_COUNT; ++i)
139 (*this)[i] *= rhs[i];
146 for (
size_t i = 0; i < ITEM_COUNT; ++i)
148 (*this)[i] *= scalar;
155 for (
size_t i = 0; i < ITEM_COUNT; ++i)
157 (*this)[i] /= rhs[i];
164 if constexpr (std::is_floating_point_v<ITEM_TYPE>)
167 for (
size_t i = 0; i < ITEM_COUNT; ++i)
174 for (
size_t i = 0; i < ITEM_COUNT; ++i)
176 (*this)[i] /= scalar;
226 for (
size_t i = 0; i < ITEM_COUNT; ++i)
237 for (
size_t i = 0; i < ITEM_COUNT; ++i)
239 value[i] = -value[i];
247 for (
size_t i = 0; i < ITEM_COUNT; ++i)
249 value[i] = +value[i];
302#ifdef TEST_VEC_TRAITS
303#undef TEST_VEC_TRAITS
static float4 rgba(float r, float g, float b, float a)
static float4 opaque(float3 rgb)
static constexpr float ALPHA_TRANSPARENT
static float4 transparent(float3 rgb)
static float4 rgb(float r, float g, float b)
static constexpr float ALPHA_OPAQUE
constexpr bool is_subset_of_v
nem::vec< float, 4 > float4
static constexpr size_t ITEM_COUNT
ITEM_TYPE data[ITEM_COUNT]
vec & operator*=(const vec &rhs)
vec & operator/=(ITEM_TYPE scalar)
friend vec operator/(ITEM_TYPE scalar, vec vec)
static constexpr vec NaN()
friend vec operator*(vec lhs, const vec &rhs)
friend vec operator/(vec vec, ITEM_TYPE scalar)
vec & operator/=(const vec &rhs)
friend vec operator+(vec lhs, const vec &rhs)
vec & operator*=(ITEM_TYPE scalar)
constexpr ITEM_TYPE & operator[](size_t index)
friend vec operator/(vec lhs, const vec &rhs)
friend vec operator-(vec lhs, const vec &rhs)
vec & operator+=(const vec &rhs)
friend vec operator*(ITEM_TYPE scalar, vec vec)
vec & operator-=(const vec &rhs)
constexpr const ITEM_TYPE & operator[](size_t index) const
friend vec operator-(vec value)
friend vec operator+(vec value)
friend vec operator*(vec vec, ITEM_TYPE scalar)
#define TEST_VEC_TRAITS(VecType)