From 90fa45bb9f430decea00e22ddafdd351048e57ba Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Sat, 22 Jun 2019 16:27:03 +0200 Subject: Update CMakeLists and structure under include --- CMakeLists.txt | 6 +- include/mm | 11 -- include/mm/mm.hpp | 11 ++ include/mm/mmvec.hpp | 319 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/mmvec.hpp | 319 --------------------------------------------------- mmvec.cpp | 2 +- test/vec_example.cpp | 2 +- 7 files changed, 335 insertions(+), 335 deletions(-) delete mode 100644 include/mm create mode 100644 include/mm/mm.hpp create mode 100644 include/mm/mmvec.hpp delete mode 100644 include/mmvec.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 04faebb..ed126da 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ target_include_directories(mm $ PRIVATE ${CMAKE_CURRENT_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/include/mm + ${CMAKE_CURRENT_SOURCE_DIR}/include ) target_compile_options(mm @@ -67,8 +67,8 @@ set_target_properties(mm PROPERTIES EXPORT_NAME MM) # install public headers install( FILES - ${CMAKE_CURRENT_SOURCE_DIR}/include/mmvec.hpp - ${CMAKE_CURRENT_SOURCE_DIR}/include/mm + ${CMAKE_CURRENT_SOURCE_DIR}/include/mm/mmvec.hpp + ${CMAKE_CURRENT_SOURCE_DIR}/include/mm/mm.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mm ) diff --git a/include/mm b/include/mm deleted file mode 100644 index 7e9f02b..0000000 --- a/include/mm +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -/* MiniMath - * A mathematical vector library that (ab)uses modern C++ abstraction features. - * This header includes the entire library. - * - * Warning: having (ab)used a lot of templated code it is not recommended to - * include everything as it may slow down the compiler. - */ - -#include "mm/mmvec.hpp" diff --git a/include/mm/mm.hpp b/include/mm/mm.hpp new file mode 100644 index 0000000..7e9f02b --- /dev/null +++ b/include/mm/mm.hpp @@ -0,0 +1,11 @@ +#pragma once + +/* MiniMath + * A mathematical vector library that (ab)uses modern C++ abstraction features. + * This header includes the entire library. + * + * Warning: having (ab)used a lot of templated code it is not recommended to + * include everything as it may slow down the compiler. + */ + +#include "mm/mmvec.hpp" diff --git a/include/mm/mmvec.hpp b/include/mm/mmvec.hpp new file mode 100644 index 0000000..1939388 --- /dev/null +++ b/include/mm/mmvec.hpp @@ -0,0 +1,319 @@ +/* mmvec.hpp + * Part of Mathematical library built (ab)using Modern C++ 17 abstractions. + * + * This library is not intended to be _performant_, it does not contain + * hand written SMID / SSE / AVX optimizations. It is instead an example + * of highly abstracted code, where Vectors can contain any data type. + * + * As a challenge, the vector data structure has been built on a container + * of static capacity. But if a dynamic base container is needed, the code + * should be easily modifiable to add further abstraction, by templating + * the container, and by consequence the allocator. + * + * Naoki Pross + * 2018 ~ 2019 + */ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace mm { + // generic implementation + template + struct basic_vec; + + // usable specializations + template + struct vec; + template + struct vec3; + template + struct vec2; +} + +template +struct mm::basic_vec : public std::array { + using type = T; + static constexpr std::size_t dimensions = d; + + // TODO: template away these + static constexpr T null_element = static_cast(0); + static constexpr T unit_element = static_cast(1); + static constexpr T unit_additive_inverse_element = static_cast(-1); + + basic_vec(); + basic_vec(const std::initializer_list l); + + // copyable to a vector of size n <= d + template basic_vec(const basic_vec& other); + // movable to a vector of size n <= d + template basic_vec(basic_vec&& other); + + T length() const; + + // copy operator= + template + basic_vec& operator=(const mm::basic_vec& other); + + // move operator= + template + basic_vec& operator=(mm::basic_vec&& other); + + template + basic_vec& operator+=(const mm::basic_vec& other); + + template + basic_vec& operator-=(const mm::basic_vec& other); + + + basic_vec& operator*=(const T& scalar); +}; + + +// member functions for basic_vec + +template +mm::basic_vec::basic_vec() : std::array() { + this->fill(basic_vec::null_element); +} + +template +mm::basic_vec::basic_vec(const std::initializer_list l) { + // why can't this sh*t be a constexpr with static_assert??? + assert(l.size() <= d); + std::copy(l.begin(), l.end(), this->begin()); +} + +template +template +mm::basic_vec::basic_vec(const mm::basic_vec& other) { + *this = other; +} + +template +template +mm::basic_vec::basic_vec(basic_vec&& other) { + *this = other; +} + +template +T mm::basic_vec::length() const { + return std::sqrt(std::accumulate(this->begin(), this->end(), + basic_vec::null_element, + [](const T& init, const T& val) -> T { + return init + val * val; + } + )); +} + + +// memeber operator overloads for basic_vec + +template +template +mm::basic_vec& mm::basic_vec::operator=(const mm::basic_vec& other) { + static_assert( + d >= n, "cannot copy higher dimensional vector into a smaller one" + ); + + std::copy(other.begin(), other.end(), this->begin()); + + return *this; +} + +template +template +mm::basic_vec& mm::basic_vec::operator=(mm::basic_vec&& other) { + static_assert( + d >= n, "cannot move a higher dimensional vector into a smaller one" + ); + + std::move(other.begin(), other.end(), this->begin()); + + return *this; +} + + +template +template +mm::basic_vec& mm::basic_vec::operator+=(const mm::basic_vec& other) { + *this = *this + other; + return *this; +} + +template +template +mm::basic_vec& mm::basic_vec::operator-=(const mm::basic_vec& other) { + *this = *this - other; + return *this; +} + +template +mm::basic_vec& mm::basic_vec::operator*=(const T& scalar) { + *this = *this * scalar; + return *this; +} + + +// operator overloads for basic_vec + +template +mm::basic_vec operator+(const mm::basic_vec& rhs, const mm::basic_vec& lhs) { + mm::basic_vec out; + + std::transform(rhs.begin(), rhs.end(), lhs.begin(), out.begin(), + [](const T& r, const T& l) -> T { + return r + l; + } + ); + + return out; +} + +template +mm::basic_vec operator*(const mm::basic_vec& rhs, const T& lhs) { + return lhs * rhs; +} + +template +mm::basic_vec operator*(const T& rhs, const mm::basic_vec& lhs) { + mm::basic_vec out; + + std::transform(lhs.begin(), lhs.end(), out.begin(), + [rhs](const T& t) -> T { + return t * rhs; + }); + + return out; +} + +template +mm::basic_vec operator-(const mm::basic_vec& rhs, const mm::basic_vec& lhs) { + return rhs + mm::basic_vec::unit_additive_inverse_element * lhs; +} + +template +T operator*(const mm::basic_vec& rhs, const mm::basic_vec& lhs) { + return std::inner_product(rhs.begin(), rhs.end(), lhs.begin(), 0); +} + +template +std::ostream& operator<<(std::ostream& os, const mm::basic_vec& v) { + os << "<"; + std::for_each(v.begin(), v.end() -1, [&](const T& el) { + os << el << ", "; + }); + os << v.back() << ">"; + + return os; +} + + +// actual vectors to use in your code + +template +class mm::vec: public mm::basic_vec { +public: + using mm::basic_vec::basic_vec; +}; + + +// three dimensional specialization with a static cross product +// TODO: specialize operator+ for spherical coordinates + +template +class mm::vec3 : public mm::basic_vec { +public: + using mm::basic_vec::basic_vec; + + T& x() { return this->at(0); } + T& y() { return this->at(1); } + T& z() { return this->at(2); } + + const T& x() const { return this->at(0); } + const T& y() const { return this->at(1); } + const T& z() const { return this->at(2); } + + T zenith() const; + T azimuth() const; + vec3 spherical() const; + + static vec3 cross(const vec3& rhs, const vec3& lhs); +}; + +template +T mm::vec3::zenith() const { + return std::acos(this->z() / this->length()); +} + +template +T mm::vec3::azimuth() const { + return std::atan(this->y() / this->x()); +} + +template +mm::vec3 mm::vec3::spherical() const { + return mm::vec3 { + this->length(), + this->zenith(), + this->azimuth(), + }; +} + +template +mm::vec3 mm::vec3::cross(const vec3& rhs, const vec3& lhs) { + mm::vec3 res; + + res.x() = (rhs.y() * lhs.z()) - (rhs.z() * lhs.y()); + res.y() = (rhs.z() * lhs.x()) - (rhs.x() * lhs.z()); + res.z() = (rhs.x() * lhs.y()) - (rhs.y() * lhs.x()); + + return res; +} + + +// two dimensional specialization with a polar conversion +// TODO: specialize operator+ for polar coordinates + +template +class mm::vec2: public mm::basic_vec { +public: + using mm::basic_vec::basic_vec; + + T& x() { return this->at(0); } + T& y() { return this->at(1); } + + const T& x() const { return this->at(0); } + const T& y() const { return this->at(1); } + + T angle() const; + vec2 polar() const; + + static vec3 cross(const vec2& rhs, const vec2& lhs); +}; + +template +T mm::vec2::angle() const { + return std::atan(this->y() / this->x()); +} + +template +mm::vec2 mm::vec2::polar() const { + return { + this->length(), + this->angle() + }; +} + +template +mm::vec3 mm::vec2::cross(const mm::vec2& rhs, const mm::vec2& lhs) { + return mm::vec3::cross(mm::vec3(rhs), mm::vec3(lhs)); +} diff --git a/include/mmvec.hpp b/include/mmvec.hpp deleted file mode 100644 index 1939388..0000000 --- a/include/mmvec.hpp +++ /dev/null @@ -1,319 +0,0 @@ -/* mmvec.hpp - * Part of Mathematical library built (ab)using Modern C++ 17 abstractions. - * - * This library is not intended to be _performant_, it does not contain - * hand written SMID / SSE / AVX optimizations. It is instead an example - * of highly abstracted code, where Vectors can contain any data type. - * - * As a challenge, the vector data structure has been built on a container - * of static capacity. But if a dynamic base container is needed, the code - * should be easily modifiable to add further abstraction, by templating - * the container, and by consequence the allocator. - * - * Naoki Pross - * 2018 ~ 2019 - */ -#pragma once - -#include -#include - -#include -#include -#include -#include -#include -#include - -namespace mm { - // generic implementation - template - struct basic_vec; - - // usable specializations - template - struct vec; - template - struct vec3; - template - struct vec2; -} - -template -struct mm::basic_vec : public std::array { - using type = T; - static constexpr std::size_t dimensions = d; - - // TODO: template away these - static constexpr T null_element = static_cast(0); - static constexpr T unit_element = static_cast(1); - static constexpr T unit_additive_inverse_element = static_cast(-1); - - basic_vec(); - basic_vec(const std::initializer_list l); - - // copyable to a vector of size n <= d - template basic_vec(const basic_vec& other); - // movable to a vector of size n <= d - template basic_vec(basic_vec&& other); - - T length() const; - - // copy operator= - template - basic_vec& operator=(const mm::basic_vec& other); - - // move operator= - template - basic_vec& operator=(mm::basic_vec&& other); - - template - basic_vec& operator+=(const mm::basic_vec& other); - - template - basic_vec& operator-=(const mm::basic_vec& other); - - - basic_vec& operator*=(const T& scalar); -}; - - -// member functions for basic_vec - -template -mm::basic_vec::basic_vec() : std::array() { - this->fill(basic_vec::null_element); -} - -template -mm::basic_vec::basic_vec(const std::initializer_list l) { - // why can't this sh*t be a constexpr with static_assert??? - assert(l.size() <= d); - std::copy(l.begin(), l.end(), this->begin()); -} - -template -template -mm::basic_vec::basic_vec(const mm::basic_vec& other) { - *this = other; -} - -template -template -mm::basic_vec::basic_vec(basic_vec&& other) { - *this = other; -} - -template -T mm::basic_vec::length() const { - return std::sqrt(std::accumulate(this->begin(), this->end(), - basic_vec::null_element, - [](const T& init, const T& val) -> T { - return init + val * val; - } - )); -} - - -// memeber operator overloads for basic_vec - -template -template -mm::basic_vec& mm::basic_vec::operator=(const mm::basic_vec& other) { - static_assert( - d >= n, "cannot copy higher dimensional vector into a smaller one" - ); - - std::copy(other.begin(), other.end(), this->begin()); - - return *this; -} - -template -template -mm::basic_vec& mm::basic_vec::operator=(mm::basic_vec&& other) { - static_assert( - d >= n, "cannot move a higher dimensional vector into a smaller one" - ); - - std::move(other.begin(), other.end(), this->begin()); - - return *this; -} - - -template -template -mm::basic_vec& mm::basic_vec::operator+=(const mm::basic_vec& other) { - *this = *this + other; - return *this; -} - -template -template -mm::basic_vec& mm::basic_vec::operator-=(const mm::basic_vec& other) { - *this = *this - other; - return *this; -} - -template -mm::basic_vec& mm::basic_vec::operator*=(const T& scalar) { - *this = *this * scalar; - return *this; -} - - -// operator overloads for basic_vec - -template -mm::basic_vec operator+(const mm::basic_vec& rhs, const mm::basic_vec& lhs) { - mm::basic_vec out; - - std::transform(rhs.begin(), rhs.end(), lhs.begin(), out.begin(), - [](const T& r, const T& l) -> T { - return r + l; - } - ); - - return out; -} - -template -mm::basic_vec operator*(const mm::basic_vec& rhs, const T& lhs) { - return lhs * rhs; -} - -template -mm::basic_vec operator*(const T& rhs, const mm::basic_vec& lhs) { - mm::basic_vec out; - - std::transform(lhs.begin(), lhs.end(), out.begin(), - [rhs](const T& t) -> T { - return t * rhs; - }); - - return out; -} - -template -mm::basic_vec operator-(const mm::basic_vec& rhs, const mm::basic_vec& lhs) { - return rhs + mm::basic_vec::unit_additive_inverse_element * lhs; -} - -template -T operator*(const mm::basic_vec& rhs, const mm::basic_vec& lhs) { - return std::inner_product(rhs.begin(), rhs.end(), lhs.begin(), 0); -} - -template -std::ostream& operator<<(std::ostream& os, const mm::basic_vec& v) { - os << "<"; - std::for_each(v.begin(), v.end() -1, [&](const T& el) { - os << el << ", "; - }); - os << v.back() << ">"; - - return os; -} - - -// actual vectors to use in your code - -template -class mm::vec: public mm::basic_vec { -public: - using mm::basic_vec::basic_vec; -}; - - -// three dimensional specialization with a static cross product -// TODO: specialize operator+ for spherical coordinates - -template -class mm::vec3 : public mm::basic_vec { -public: - using mm::basic_vec::basic_vec; - - T& x() { return this->at(0); } - T& y() { return this->at(1); } - T& z() { return this->at(2); } - - const T& x() const { return this->at(0); } - const T& y() const { return this->at(1); } - const T& z() const { return this->at(2); } - - T zenith() const; - T azimuth() const; - vec3 spherical() const; - - static vec3 cross(const vec3& rhs, const vec3& lhs); -}; - -template -T mm::vec3::zenith() const { - return std::acos(this->z() / this->length()); -} - -template -T mm::vec3::azimuth() const { - return std::atan(this->y() / this->x()); -} - -template -mm::vec3 mm::vec3::spherical() const { - return mm::vec3 { - this->length(), - this->zenith(), - this->azimuth(), - }; -} - -template -mm::vec3 mm::vec3::cross(const vec3& rhs, const vec3& lhs) { - mm::vec3 res; - - res.x() = (rhs.y() * lhs.z()) - (rhs.z() * lhs.y()); - res.y() = (rhs.z() * lhs.x()) - (rhs.x() * lhs.z()); - res.z() = (rhs.x() * lhs.y()) - (rhs.y() * lhs.x()); - - return res; -} - - -// two dimensional specialization with a polar conversion -// TODO: specialize operator+ for polar coordinates - -template -class mm::vec2: public mm::basic_vec { -public: - using mm::basic_vec::basic_vec; - - T& x() { return this->at(0); } - T& y() { return this->at(1); } - - const T& x() const { return this->at(0); } - const T& y() const { return this->at(1); } - - T angle() const; - vec2 polar() const; - - static vec3 cross(const vec2& rhs, const vec2& lhs); -}; - -template -T mm::vec2::angle() const { - return std::atan(this->y() / this->x()); -} - -template -mm::vec2 mm::vec2::polar() const { - return { - this->length(), - this->angle() - }; -} - -template -mm::vec3 mm::vec2::cross(const mm::vec2& rhs, const mm::vec2& lhs) { - return mm::vec3::cross(mm::vec3(rhs), mm::vec3(lhs)); -} diff --git a/mmvec.cpp b/mmvec.cpp index f555a6e..95c68f1 100644 --- a/mmvec.cpp +++ b/mmvec.cpp @@ -1 +1 @@ -#include "mmvec.hpp" +#include "mm/mmvec.hpp" diff --git a/test/vec_example.cpp b/test/vec_example.cpp index 3a00f58..14b9680 100644 --- a/test/vec_example.cpp +++ b/test/vec_example.cpp @@ -1,4 +1,4 @@ -#include "mmvec.hpp" +#include "mm/mmvec.hpp" #include #include -- cgit v1.2.1