#pragma once #include #include namespace shader { template struct Vector : std::array { using std::array::array; template constexpr explicit operator Vector() const { Vector result; for (std::size_t i = 0; i < N; ++i) { result[i] = static_cast((*this)[i]); } return result; } #define DEFINE_BINOP(OP) \ constexpr auto operator OP(const Vector &other) const \ requires requires(T lhs, T rhs) { lhs OP rhs; } \ { \ using ResultElementT = \ std::remove_cvref_t() OP std::declval())>; \ Vector result; \ for (std::size_t i = 0; i < N; ++i) { \ result[i] = (*this)[i] OP other[i]; \ } \ return result; \ } \ constexpr auto operator OP(const T &other) const \ requires requires(T lhs, T rhs) { lhs OP rhs; } \ { \ using ResultElementT = \ std::remove_cvref_t() OP std::declval())>; \ Vector result; \ for (std::size_t i = 0; i < N; ++i) { \ result[i] = (*this)[i] OP other; \ } \ return result; \ } #define DEFINE_UNOP(OP) \ constexpr auto operator OP() const \ requires requires(T rhs) { OP rhs; } \ { \ using ResultElementT = \ std::remove_cvref_t())>; \ Vector result; \ for (std::size_t i = 0; i < N; ++i) { \ result[i] = OP(*this)[i]; \ } \ return result; \ } DEFINE_BINOP(+) DEFINE_BINOP(-) DEFINE_BINOP(*) DEFINE_BINOP(/) DEFINE_BINOP(%) DEFINE_BINOP(&) DEFINE_BINOP(|) DEFINE_BINOP(^) DEFINE_BINOP(>>) DEFINE_BINOP(<<) DEFINE_BINOP(&&) DEFINE_BINOP(||) DEFINE_BINOP(<) DEFINE_BINOP(>) DEFINE_BINOP(<=) DEFINE_BINOP(>=) DEFINE_BINOP(==) DEFINE_BINOP(!=) DEFINE_UNOP(-) DEFINE_UNOP(~) DEFINE_UNOP(!) #undef DEFINE_BINOP #undef DEFINE_UNOP }; using float16_t = _Float16; using float32_t = float; using float64_t = double; using u8vec2 = Vector; using u8vec3 = Vector; using u8vec4 = Vector; using i8vec2 = Vector; using i8vec3 = Vector; using i8vec4 = Vector; using u16vec2 = Vector; using u16vec3 = Vector; using u16vec4 = Vector; using i16vec2 = Vector; using i16vec3 = Vector; using i16vec4 = Vector; using u32vec2 = Vector; using u32vec3 = Vector; using u32vec4 = Vector; using i32vec2 = Vector; using i32vec3 = Vector; using i32vec4 = Vector; using u64vec2 = Vector; using u64vec3 = Vector; using u64vec4 = Vector; using i64vec2 = Vector; using i64vec3 = Vector; using i64vec4 = Vector; using f32vec2 = Vector; using f32vec3 = Vector; using f32vec4 = Vector; using f64vec2 = Vector; using f64vec3 = Vector; using f64vec4 = Vector; using f16vec2 = Vector; using f16vec3 = Vector; using f16vec4 = Vector; using bvec2 = Vector; using bvec3 = Vector; using bvec4 = Vector; } // namespace shader