#ifndef MATH_VECTOR_HPP #define MATH_VECTOR_HPP 1 #include #include namespace mvec { template requires(std::is_arithmetic_v) class vec { protected: std::array v; public: constexpr vec(const std::array &vs) : v(vs) {} constexpr vec(T vs) : v(vs) {} template constexpr vec &operator+=(const vec &rhs) { for(std::size_t i = 0; i < S2 && i < S; i++) v[i] += rhs[i]; return *this; } template constexpr vec &operator-=(const vec &rhs) { for(std::size_t i = 0; i < S2 && i < S; i++) v[i] -= rhs[i]; return *this; } template constexpr vec &operator*=(const vec &rhs) { for(std::size_t i = 0; i < S2 && i < S; i++) v[i] *= rhs[i]; return *this; } template constexpr vec &operator/=(const vec &rhs) { for(std::size_t i = 0; i < S2 && i < S; i++) v[i] /= rhs[i]; return *this; } template friend constexpr vec operator+(vec lhs, const vec &rhs) { lhs += rhs; return lhs; } template friend constexpr vec operator-(vec lhs, const vec &rhs) { lhs -= rhs; return lhs; } template friend constexpr vec operator*(vec lhs, const vec &rhs) { lhs *= rhs; return lhs; } template friend constexpr vec operator/(vec lhs, const vec &rhs) { lhs /= rhs; return lhs; } constexpr T &operator[](std::size_t i) { return v[i]; } constexpr T operator[](std::size_t i) const { return v[i]; } }; template requires(std::is_arithmetic_v) class vec2 final : public vec { public: T &x; T &y; constexpr vec2(T X, T Y) : vec(std::array{X, Y}), x(this->v[0]), y(this->v[1]) {} constexpr vec2(std::array vs) : vec(vs), x(this->v[0]), y(this->v[1]) {} constexpr vec2(T vs) : vec(vs), x(this->v[0]), y(this->v[1]) {} }; template requires(std::is_arithmetic_v) class vec3 final : public vec { public: T &x; T &y; T &z; constexpr vec3(T X, T Y, T Z) : vec(std::array{X, Y, Z}), x(this->v[0]), y(this->v[1]), z(this->v[2]) {} constexpr vec3(std::array vs) : vec(vs), x(this->v[0]), y(this->v[1]), z(this->v[2]) {} constexpr vec3(T vs) : vec(vs), x(this->v[0]), y(this->v[1]), z(this->v[2]) {} }; template requires(std::is_arithmetic_v) class vec4 final : public vec { public: T &x; T &y; T &z; T &w; constexpr vec4(T X, T Y, T Z, T W) : vec(std::array{X, Y, Z, W}), x(this->v[0]), y(this->v[1]), z(this->v[2]), w(this->v[3]) {} constexpr vec4(std::array vs) : vec(vs), x(this->v[0]), y(this->v[1]), z(this->v[2]), w(this->v[3]) {} constexpr vec4(T vs) : vec(vs), x(this->v[0]), y(this->v[1]), z(this->v[2]), w(this->v[3]) {} }; } #endif