#include #include #include #include #include template class basic_vec { public: typedef T value_type; typedef typename std::array::iterator iterator; typedef typename std::array::const_iterator const_iterator; static constexpr std::size_t dimensions = d; basic_vec(); basic_vec(std::initializer_list l); template basic_vec(const basic_vec& other); T length() const; T& operator[](std::size_t idx); const T& operator[](std::size_t idx) const; iterator begin(); const_iterator cbegin() const; iterator end(); const_iterator cend() const; private: std::array m_data; }; template basic_vec::basic_vec() { m_data.fill(static_cast(0)); } template basic_vec::basic_vec(std::initializer_list l) { assert(l.size() <= d); m_data.fill(static_cast(0)); std::copy(l.begin(), l.end(), m_data.begin()); } template template basic_vec::basic_vec(const basic_vec& other) { static_assert(d >= n); m_data.fill(static_cast(0)); for (std::size_t i = 0; i < n; i++) { m_data[i] = other[i]; } } template T basic_vec::length() const { T res = static_cast(0); for (const T& val : m_data) { res += val * val; } return res; } template T& basic_vec::operator[](std::size_t idx) { return m_data[idx]; } template const T& basic_vec::operator[](std::size_t idx) const { return m_data[idx]; } template typename basic_vec::iterator basic_vec::begin() { return m_data.begin(); } template typename basic_vec::const_iterator basic_vec::cbegin() const { return m_data.cbegin(); } template typename basic_vec::iterator basic_vec::end() { return m_data.end(); } template typename basic_vec::const_iterator basic_vec::cend() const { return m_data.cend(); } template basic_vec operator+(const basic_vec& rhs, const basic_vec& lhs) { basic_vec out; auto rit = rhs.cbegin(), lit = lhs.cbegin(); std::generate(out.begin(), out.end(), [rit, lit] () mutable { return *(rit++) + *(lit++); }); return out; } template basic_vec operator*(const T& rhs, const basic_vec& lhs) { basic_vec out; auto lit = lhs.cbegin(); std::generate(out.begin(), out.end(), [rhs, lit] () mutable { return rhs * *(lit++); }); return out; } template basic_vec operator-(const basic_vec& rhs, const basic_vec& lhs) { return rhs + static_cast(-1) * lhs; } template T operator*(const basic_vec& rhs, const basic_vec& lhs) { T res = static_cast(0); for (std::size_t i = 0; i < d; i++) { res += rhs[i] * lhs[i]; } return res; } template std::ostream& operator<<(std::ostream& os, const basic_vec& v) { os << "<"; for (std::size_t i = 0; i < d -1; i++) { os << v[i] << ", "; } os << v[d-1] << ">"; return os; } template class vec: public basic_vec { public: vec(std::initializer_list l) : basic_vec(l) {} }; template class vec3 : public basic_vec { public: vec3(std::initializer_list l) : basic_vec(l) {} static vec3 cross(const vec3& rhs, const vec3& lhs); }; template vec3 vec3::cross(const vec3& rhs, const vec3& lhs) { vec3 res; // TODO: cross product return res; } template class vec2: public basic_vec { public: vec2(std::initializer_list l) : basic_vec(l) {} T angle(); static vec3 cross(const vec2& rhs, const vec2& lhs); }; template vec3 vec2::cross(const vec2& rhs, const vec2& lhs) { vec3 res; // TODO: cross product } int main(int argc, char *argv[]) { vec3 v{1, 2, 3}; vec3 u{3, 4, 5}; std::cout << v << std::endl; std::cout << v.length() << std::endl; std::cout << v + u << std::endl; std::cout << v - u << std::endl; std::cout << 2.0 * u << std::endl; std::cout << v * u << std::endl; return 0; }