diff options
author | Nao Pross <naopross@thearcway.org> | 2018-12-10 13:51:07 +0100 |
---|---|---|
committer | Nao Pross <naopross@thearcway.org> | 2018-12-10 13:51:07 +0100 |
commit | dbc65422bc4da51852764d6130d6bd8983aef7d8 (patch) | |
tree | ee98b364eaa3fa8f91e1bcbd25c7682e3c52cf6d /vector | |
parent | Update vector ex. makefile and add vec3_mag function (diff) | |
download | cplusplus-dbc65422bc4da51852764d6130d6bd8983aef7d8.tar.gz cplusplus-dbc65422bc4da51852764d6130d6bd8983aef7d8.zip |
Add C++ templated vector example
Diffstat (limited to '')
-rw-r--r-- | vector/makefile | 4 | ||||
-rw-r--r-- | vector/vector.cpp | 195 |
2 files changed, 197 insertions, 2 deletions
diff --git a/vector/makefile b/vector/makefile index ad56656..d504a71 100644 --- a/vector/makefile +++ b/vector/makefile @@ -1,8 +1,8 @@ CARGS := -Wall -Werror -I. LDARGS := -lm -CPPARGS := -Wall -Werror -I. +CPPARGS := -Wall -I. -all: vector.pdf c_build/vector +all: vector.pdf c_build/vector cpp_build/vector %.pdf: %.md pandoc \ 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; +} |