summaryrefslogtreecommitdiffstats
path: root/vector/vector.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--vector/vector.cpp195
1 files changed, 195 insertions, 0 deletions
diff --git a/vector/vector.cpp b/vector/vector.cpp
new file mode 100644
index 0000000..972ade2
--- /dev/null
+++ b/vector/vector.cpp
@@ -0,0 +1,195 @@
+#include <iostream>
+
+#include <cassert>
+#include <array>
+#include <initializer_list>
+#include <algorithm>
+
+template<typename T, std::size_t d>
+class basic_vec {
+public:
+ typedef T value_type;
+ typedef typename std::array<T, d>::iterator iterator;
+ typedef typename std::array<T, d>::const_iterator const_iterator;
+
+ static constexpr std::size_t dimensions = d;
+
+ basic_vec();
+ basic_vec(std::initializer_list<T> l);
+ template<std::size_t n>
+ basic_vec(const basic_vec<T, n>& 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<T, d> m_data;
+};
+
+template<typename T, std::size_t d>
+basic_vec<T, d>::basic_vec() {
+ m_data.fill(static_cast<T>(0));
+}
+
+template<typename T, std::size_t d>
+basic_vec<T, d>::basic_vec(std::initializer_list<T> l) {
+ assert(l.size() <= d);
+ m_data.fill(static_cast<T>(0));
+ std::copy(l.begin(), l.end(), m_data.begin());
+}
+
+template<typename T, std::size_t d>
+template<std::size_t n>
+basic_vec<T, d>::basic_vec(const basic_vec<T, n>& other) {
+ static_assert(d >= n);
+ m_data.fill(static_cast<T>(0));
+ for (std::size_t i = 0; i < n; i++) {
+ m_data[i] = other[i];
+ }
+}
+
+template<typename T, std::size_t d>
+T basic_vec<T, d>::length() const {
+ T res = static_cast<T>(0);
+ for (const T& val : m_data) {
+ res += val * val;
+ }
+
+ return res;
+}
+
+template<typename T, std::size_t d>
+T& basic_vec<T, d>::operator[](std::size_t idx) {
+ return m_data[idx];
+}
+
+template<typename T, std::size_t d>
+const T& basic_vec<T, d>::operator[](std::size_t idx) const {
+ return m_data[idx];
+}
+
+template<typename T, std::size_t d>
+typename basic_vec<T, d>::iterator basic_vec<T, d>::begin() {
+ return m_data.begin();
+}
+
+template<typename T, std::size_t d>
+typename basic_vec<T, d>::const_iterator basic_vec<T, d>::cbegin() const {
+ return m_data.cbegin();
+}
+
+template<typename T, std::size_t d>
+typename basic_vec<T, d>::iterator basic_vec<T, d>::end() {
+ return m_data.end();
+}
+
+template<typename T, std::size_t d>
+typename basic_vec<T, d>::const_iterator basic_vec<T, d>::cend() const {
+ return m_data.cend();
+}
+
+template<typename T, std::size_t d>
+basic_vec<T, d> operator+(const basic_vec<T, d>& rhs, const basic_vec<T, d>& lhs) {
+ basic_vec<T, d> out;
+ auto rit = rhs.cbegin(), lit = lhs.cbegin();
+ std::generate(out.begin(), out.end(), [rit, lit] () mutable {
+ return *(rit++) + *(lit++);
+ });
+
+ return out;
+}
+
+template<typename T, std::size_t d>
+basic_vec<T, d> operator*(const T& rhs, const basic_vec<T, d>& lhs) {
+ basic_vec<T, d> out;
+ auto lit = lhs.cbegin();
+
+ std::generate(out.begin(), out.end(), [rhs, lit] () mutable {
+ return rhs * *(lit++);
+ });
+
+ return out;
+}
+
+template<typename T, std::size_t d>
+basic_vec<T, d> operator-(const basic_vec<T, d>& rhs, const basic_vec<T, d>& lhs) {
+ return rhs + static_cast<T>(-1) * lhs;
+}
+
+template<typename T, std::size_t d>
+T operator*(const basic_vec<T, d>& rhs, const basic_vec<T, d>& lhs) {
+ T res = static_cast<T>(0);
+ for (std::size_t i = 0; i < d; i++) {
+ res += rhs[i] * lhs[i];
+ }
+
+ return res;
+}
+
+template<typename T, std::size_t d>
+std::ostream& operator<<(std::ostream& os, const basic_vec<T, d>& v) {
+ os << "<";
+ for (std::size_t i = 0; i < d -1; i++) {
+ os << v[i] << ", ";
+ }
+ os << v[d-1] << ">";
+ return os;
+}
+
+
+template<typename T, std::size_t d>
+class vec: public basic_vec<T, d> {
+public:
+ vec(std::initializer_list<T> l) : basic_vec<T, d>(l) {}
+};
+
+template<typename T>
+class vec3 : public basic_vec<T, 3> {
+public:
+ vec3(std::initializer_list<T> l) : basic_vec<T, 3>(l) {}
+ static vec3<T> cross(const vec3<T>& rhs, const vec3<T>& lhs);
+};
+
+template<typename T>
+vec3<T> vec3<T>::cross(const vec3<T>& rhs, const vec3<T>& lhs) {
+ vec3<T> res;
+ // TODO: cross product
+
+ return res;
+}
+
+
+template<typename T>
+class vec2: public basic_vec<T, 2> {
+public:
+ vec2(std::initializer_list<T> l) : basic_vec<T, 2>(l) {}
+ T angle();
+ static vec3<T> cross(const vec2<T>& rhs, const vec2<T>& lhs);
+};
+
+template<typename T>
+vec3<T> vec2<T>::cross(const vec2<T>& rhs, const vec2<T>& lhs) {
+ vec3<T> res;
+ // TODO: cross product
+}
+
+
+int main(int argc, char *argv[]) {
+ vec3<double> v{1, 2, 3};
+ vec3<double> 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;
+}