#pragma once #include #include #include #include template struct Vector { public: Vector(): elements{} {}; template Vector(Args... args) : elements{ args... } {}; Vector(T values[S]) { std::copy(values, values + S, elements); }; Vector(Vector vector, T scalar) { std::copy(vector.elements, vector.elements + S - 1, elements); elements[S - 1] = scalar; } Vector apply(T f(T)) { return apply(static_cast>(f)); } Vector apply(std::function f) { Vector result{}; for (int i = 0; i < S; i++) { result[i] = f(elements[i]); } return result; } T& operator[](size_t index) { return elements[index]; } Vector operator+(Vector other) const { Vector result{}; for (int i = 0; i < S; i++) { result[i] = elements[i] + other[i]; } return result; } Vector operator*(T scalar) const { Vector result; for (size_t index; index < S; index++) { result = this[index] * scalar; } return result; } T operator*(Vector other) const { T result = 0; for (size_t index = 0; index < S; index++) { result += this->elements[index] * other[index]; } return result; } T x() { static_assert(S > 0); return elements[0]; } T y() { static_assert(S > 1); return elements[1]; } T z() { static_assert(S > 2); return elements[2]; } T w() { static_assert(S > 3); return elements[3]; } std::string string() const { std::stringstream str{}; str << "[ "; for (int i = 0; i < S; i++) { str << elements[i] << " "; } str << "]"; return str.str(); } T elements[S]; };