From 1ba41e14b060bc4d0381c85a319d67eb4c49f63b Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 14 Feb 2021 22:03:06 +0700 Subject: [PATCH 01/15] remove isnan, isinf, isfinite, modf, frexp and ldexp functions --- README.md | 45 --------------------------- headers/vmath.hpp/vmath_fun.hpp | 36 ---------------------- headers/vmath.hpp/vmath_qua_fun.hpp | 15 --------- headers/vmath.hpp/vmath_vec_fun.hpp | 48 ----------------------------- untests/vmath_fun_tests.cpp | 18 ----------- untests/vmath_qua_fun_tests.cpp | 6 ---- untests/vmath_tests.hpp | 2 +- untests/vmath_vec_fun_tests.cpp | 18 ----------- 8 files changed, 1 insertion(+), 187 deletions(-) diff --git a/README.md b/README.md index 2b7fa5a..6bd7672 100644 --- a/README.md +++ b/README.md @@ -947,9 +947,6 @@ T fract(T x) noexcept; template < floating_point T > T fmod(T x, T y) noexcept; -template < floating_point T > -T modf(T x, T* y) noexcept; - template < floating_point T > T copysign(T x, T s) noexcept; @@ -977,23 +974,8 @@ constexpr T step(T edge, T x) noexcept; template < floating_point T > constexpr T smoothstep(T edge0, T edge1, T x) noexcept; -template < arithmetic T > -bool isnan(T x) noexcept; - -template < arithmetic T > -bool isinf(T x) noexcept; - -template < arithmetic T > -bool isfinite(T x) noexcept; - template < floating_point T > T fma(T x, T y, T z) noexcept; - -template < floating_point T > -T frexp(T x, int* exp) noexcept; - -template < floating_point T > -T ldexp(T x, int exp) noexcept; ``` #### Vector @@ -1032,9 +1014,6 @@ vec fmod(const vec& xs, T y); template < typename T, size_t Size > vec fmod(const vec& xs, const vec& ys); -template < typename T, size_t Size > -vec modf(const vec& xs, vec* is); - template < typename T, size_t Size > vec copysign(const vec& xs, T s); @@ -1098,23 +1077,8 @@ constexpr vec smoothstep(T edge0, T edge1, const vec& xs); template < typename T, size_t Size > constexpr vec smoothstep(const vec& edges0, const vec& edges1, const vec& xs); -template < typename T, size_t Size > -vec isnan(const vec& xs); - -template < typename T, size_t Size > -vec isinf(const vec& xs); - -template < typename T, size_t Size > -vec isfinite(const vec& xs); - template < typename T, size_t Size > vec fma(const vec& as, const vec& bs, const vec& cs); - -template < typename T, size_t Size > -vec frexp(const vec& xs, vec* exps); - -template < typename T, size_t Size > -vec ldexp(const vec& xs, const vec& exps); ``` #### Quaternion @@ -1131,15 +1095,6 @@ qua nlerp(const qua& unit_xs, const qua& unit_ys, T a); template < typename T > qua slerp(const qua& unit_xs, const qua& unit_ys, T a); - -template < typename T > -vec isnan(const qua& xs); - -template < typename T > -vec isinf(const qua& xs); - -template < typename T > -vec isfinite(const qua& xs); ``` ### Angle and Trigonometric Functions diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index ad675d2..0e43580 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -80,12 +80,6 @@ namespace vmath_hpp return std::fmod(x, y); } - template < typename T > - [[nodiscard]] std::enable_if_t, T> - modf(T x, T* y) noexcept { - return std::modf(x, y); - } - template < typename T > [[nodiscard]] std::enable_if_t, T> copysign(T x, T s) noexcept { @@ -141,41 +135,11 @@ namespace vmath_hpp return t * t * (T(3) - T(2) * t); } - template < typename T > - [[nodiscard]] std::enable_if_t, bool> - isnan(T x) noexcept { - return std::isnan(x); - } - - template < typename T > - [[nodiscard]] std::enable_if_t, bool> - isinf(T x) noexcept { - return std::isinf(x); - } - - template < typename T > - [[nodiscard]] std::enable_if_t, bool> - isfinite(T x) noexcept { - return std::isfinite(x); - } - template < typename T > [[nodiscard]] std::enable_if_t, T> fma(T x, T y, T z) noexcept { return std::fma(x, y, z); } - - template < typename T > - [[nodiscard]] std::enable_if_t, T> - frexp(T x, int* exp) noexcept { - return std::frexp(x, exp); - } - - template < typename T > - [[nodiscard]] std::enable_if_t, T> - ldexp(T x, int exp) noexcept { - return std::ldexp(x, exp); - } } // diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index b9bde5f..59d1624 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -196,21 +196,6 @@ namespace vmath_hpp return normalize(lerp(unit_xs, unit_ys, xs_scale, ys_scale)); } } - - template < typename T > - [[nodiscard]] vec isnan(const qua& xs) { - return isnan(vec{xs}); - } - - template < typename T > - [[nodiscard]] vec isinf(const qua& xs) { - return isinf(vec{xs}); - } - - template < typename T > - [[nodiscard]] vec isfinite(const qua& xs) { - return isfinite(vec{xs}); - } } // diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index a91ce26..0218a43 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -556,20 +556,6 @@ namespace vmath_hpp return map_join([](T x, T y) { return fmod(x, y); }, xs, ys); } - namespace impl - { - template < typename T, std::size_t Size, std::size_t... Is > - VMATH_HPP_FORCE_INLINE - vec modf_impl(const vec& xs, vec* is, std::index_sequence) { - return { modf(xs[Is], &(*is)[Is])... }; - } - } - - template < typename T, std::size_t Size > - vec modf(const vec& xs, vec* is) { - return impl::modf_impl(xs, is, std::make_index_sequence{}); - } - template < typename T, std::size_t Size > [[nodiscard]] vec copysign(const vec& xs, T s) { return map_join([s](T x) { return copysign(x, s); }, xs); @@ -684,44 +670,10 @@ namespace vmath_hpp return map_join([](T edge0, T edge1, T x) { return smoothstep(edge0, edge1, x); }, edges0, edges1, xs); } - template < typename T, std::size_t Size > - [[nodiscard]] vec isnan(const vec& xs) { - return map_join([](T x) { return isnan(x); }, xs); - } - - template < typename T, std::size_t Size > - [[nodiscard]] vec isinf(const vec& xs) { - return map_join([](T x) { return isinf(x); }, xs); - } - - template < typename T, std::size_t Size > - [[nodiscard]] vec isfinite(const vec& xs) { - return map_join([](T x) { return isfinite(x); }, xs); - } - template < typename T, std::size_t Size > [[nodiscard]] vec fma(const vec& as, const vec& bs, const vec& cs) { return map_join([](T a, T b, T c) { return fma(a, b, c); }, as, bs, cs); } - - namespace impl - { - template < typename T, std::size_t Size, std::size_t... Is > - VMATH_HPP_FORCE_INLINE - vec frexp_impl(const vec& xs, vec* exps, std::index_sequence) { - return { frexp(xs[Is], &(*exps)[Is])... }; - } - } - - template < typename T, std::size_t Size > - vec frexp(const vec& xs, vec* exps) { - return impl::frexp_impl(xs, exps, std::make_index_sequence{}); - } - - template < typename T, std::size_t Size > - [[nodiscard]] vec ldexp(const vec& xs, const vec& exps) { - return map_join([](T x, int exp) { return ldexp(x, exp); }, xs, exps); - } } // diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index 7096730..b105a74 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -77,12 +77,6 @@ TEST_CASE("vmath/fun") { CHECK(fmod(1.7f, 1.2f) == uapprox(0.5f)); - { - float out_i{}; - CHECK(modf(1.7f, &out_i) == uapprox(0.7f)); - CHECK(out_i == uapprox(1.f)); - } - STATIC_CHECK(min(0.f, 1.f) == uapprox(0.f)); STATIC_CHECK(max(0.f, 1.f) == uapprox(1.f)); @@ -106,19 +100,7 @@ TEST_CASE("vmath/fun") { STATIC_CHECK(step(0.5f, 0.6f) == uapprox(1.f)); STATIC_CHECK(smoothstep(0.f, 1.f, 0.1f) == uapprox(0.028f)); - CHECK_FALSE(vmath_hpp::isnan(1.f)); - CHECK_FALSE(vmath_hpp::isinf(1.f)); - CHECK(vmath_hpp::isfinite(1.f)); - CHECK(fma(2.f, 3.f, 4.f) == uapprox(10.f)); - - { - int out_exp{}; - CHECK(frexp(1.7f, &out_exp) == uapprox(0.85f)); - CHECK(out_exp == 1); - } - - CHECK(ldexp(0.85f, 1) == uapprox(1.7f)); } SUBCASE("Geometric Functions") { diff --git a/untests/vmath_qua_fun_tests.cpp b/untests/vmath_qua_fun_tests.cpp index f56a5e2..9b6df77 100644 --- a/untests/vmath_qua_fun_tests.cpp +++ b/untests/vmath_qua_fun_tests.cpp @@ -128,12 +128,6 @@ TEST_CASE("vmath/qua_fun") { qrotate_z(radians(290.f)), slerp(qrotate_z(radians(220.f)), qrotate_z(radians(0.f)), 0.5f)))); } - - { - CHECK_FALSE(any(isnan(qfloat(1,1,1,1)))); - CHECK_FALSE(any(isinf(qfloat(1,1,1,1)))); - CHECK(all(isfinite(qfloat(1,1,1,1)))); - } } SUBCASE("Geometric Functions") { diff --git a/untests/vmath_tests.hpp b/untests/vmath_tests.hpp index d6be42e..7b56cf7 100644 --- a/untests/vmath_tests.hpp +++ b/untests/vmath_tests.hpp @@ -57,7 +57,7 @@ namespace vmath_tests template < typename T > constexpr bool operator==(const vec& l, const uapprox2& r) { - return all(approx(l, r.value,r.epsilon)); + return all(approx(l, r.value, r.epsilon)); } template < typename T > diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index f5d54c3..873c26f 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -201,12 +201,6 @@ TEST_CASE("vmath/vec_fun") { CHECK(fmod(float2(1.7f), 1.2f) == uapprox2(0.5f)); CHECK(fmod(float2(1.7f), float2(1.2f)) == uapprox2(0.5f)); - { - float2 out_i{}; - CHECK(modf(float2(1.7f), &out_i) == uapprox2(0.7f)); - CHECK(out_i.x == uapprox(1.f)); - } - STATIC_CHECK(min(int2(1,2)) == 1); STATIC_CHECK(min(int2(1,2), 1) == int2(1,1)); STATIC_CHECK(min(1, int2(1,2)) == int2(1,1)); @@ -246,19 +240,7 @@ TEST_CASE("vmath/vec_fun") { STATIC_CHECK(smoothstep(0.f, 1.f, float2(0.1f)) == uapprox2(0.028f)); STATIC_CHECK(smoothstep(float2(0.f), float2(1.f), float2(0.1f)) == uapprox2(0.028f)); - CHECK_FALSE(isnan(float2(1.f)).x); - CHECK_FALSE(isinf(float2(1.f)).x); - CHECK(isfinite(float2(1.f)).x); - CHECK_FALSE(fma(float2(2.f), float2(3.f), float2(4.f)).x == uapprox(12.f)); - - { - int2 out_exp{}; - CHECK(frexp(float2(1.7f), &out_exp).x == uapprox(0.85f)); - CHECK(out_exp == int2(1)); - } - - CHECK(ldexp(float2(0.85f), int2(1)).x == uapprox(1.7f)); } SUBCASE("Geometric Functions") { From e3cefef78deb909f31899cf8de963575fdbfc8d4 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Fri, 19 Feb 2021 05:20:27 +0700 Subject: [PATCH 02/15] remove faceforward, reflect and refract functions --- README.md | 18 ------------------ headers/vmath.hpp/vmath_fun.hpp | 20 -------------------- headers/vmath.hpp/vmath_vec_fun.hpp | 17 ----------------- untests/vmath_fun_tests.cpp | 4 ---- untests/vmath_vec_fun_tests.cpp | 4 ---- 5 files changed, 63 deletions(-) diff --git a/README.md b/README.md index 6bd7672..c172d60 100644 --- a/README.md +++ b/README.md @@ -1283,15 +1283,6 @@ constexpr T distance2(T x, T y) noexcept; template < floating_point T > T normalize(T x) noexcept; - -template < floating_point T > -constexpr T faceforward(T n, T i, T nref) noexcept; - -template < floating_point T > -constexpr T reflect(T i, T n) noexcept; - -template < floating_point T > -T refract(T i, T n, T eta) noexcept; ``` #### Vector @@ -1320,15 +1311,6 @@ constexpr vec cross(const vec& xs, const vec& ys); template < typename T, size_t Size > vec normalize(const vec& xs); - -template < typename T, size_t Size > -constexpr vec faceforward(const vec& n, const vec& i, const vec& nref); - -template < typename T, size_t Size > -constexpr vec reflect(const vec& i, const vec& n); - -template < typename T, size_t Size > -vec refract(const vec& i, const vec& n, T eta); ``` #### Quaternion diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index 0e43580..3701c02 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -342,26 +342,6 @@ namespace vmath_hpp normalize(T x) noexcept { return x * rsqrt(length2(x)); } - - template < typename T > - [[nodiscard]] std::enable_if_t, T> - constexpr faceforward(T n, T i, T nref) noexcept { - return dot(nref, i) < T(0) ? n : -n; - } - - template < typename T > - [[nodiscard]] std::enable_if_t, T> - constexpr reflect(T i, T n) noexcept { - return i - n * dot(n, i) * T(2); - } - - template < typename T > - [[nodiscard]] std::enable_if_t, T> - refract(T i, T n, T eta) noexcept { - const T d = dot(n, i); - const T k = T(1) - eta * eta * (T(1) - d * d); - return T(k >= T(0)) * (eta * i - (eta * d + sqrt(k)) * n); - } } // diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 0218a43..979a3ec 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -861,23 +861,6 @@ namespace vmath_hpp [[nodiscard]] vec normalize(const vec& xs) { return xs * rsqrt(length2(xs)); } - - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec faceforward(const vec& n, const vec& i, const vec& nref) { - return dot(nref, i) < T(0) ? n : -n; - } - - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec reflect(const vec& i, const vec& n) { - return i - n * dot(n, i) * T(2); - } - - template < typename T, std::size_t Size > - [[nodiscard]] vec refract(const vec& i, const vec& n, T eta) { - const T d = dot(n, i); - const T k = T(1) - eta * eta * (T(1) - d * d); - return T(k >= T(0)) * (eta * i - (eta * d + sqrt(k)) * n); - } } // diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index b105a74..8de5f9a 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -118,10 +118,6 @@ TEST_CASE("vmath/fun") { STATIC_CHECK(dot(2.f, 5.f) == uapprox(10.f)); CHECK(normalize(0.5f) == uapprox(1.f)); - - STATIC_CHECK(faceforward(1.f, 2.f, 3.f) == uapprox(-1.f)); - STATIC_CHECK(reflect(1.f, 2.f) == uapprox(-7.f)); - CHECK(refract(1.f, 2.f, 1.f) == uapprox(-7.f)); } SUBCASE("Relational Functions") { diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 873c26f..88008e1 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -260,10 +260,6 @@ TEST_CASE("vmath/vec_fun") { STATIC_CHECK(cross(int2(1,0),int2(0,1)) == 1); STATIC_CHECK(cross(int3(1,0,0),int3(0,1,0)) == int3(0,0,1)); CHECK(normalize(float2(0.5f,0.f)).x == uapprox(1.f)); - - STATIC_CHECK(faceforward(float2(1.f), float2(2.f), float2(3.f)).x == uapprox(-1.f)); - STATIC_CHECK(reflect(float2(1.f), float2(2.f)).x == uapprox(-15.f)); - CHECK(refract(float2(1.f), float2(2.f), 1.f).x == uapprox(-15.f)); } SUBCASE("Relational Functions") { From 347c721a7f364103403bf993839a63dd23b62ee1 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 21 Feb 2021 00:50:38 +0700 Subject: [PATCH 03/15] basic types non-arithmetic T support --- README.md | 45 +++++++++---- headers/vmath.hpp/vmath_mat.hpp | 109 ++++++++++++++++---------------- headers/vmath.hpp/vmath_qua.hpp | 27 ++++---- headers/vmath.hpp/vmath_vec.hpp | 12 +++- 4 files changed, 111 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index c172d60..e4c5385 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,8 @@ class vec_base; template < typename T > class vec_base { public: - T x{}, y{}; + T x = T{0}; + T y = T{0}; constexpr vec_base() = default; constexpr explicit vec_base(T v); @@ -97,7 +98,9 @@ public: template < typename T > class vec_base { public: - T x{}, y{}, z{}; + T x = T{0}; + T y = T{0}; + T z = T{0}; constexpr vec_base() = default; constexpr explicit vec_base(T v); @@ -110,7 +113,10 @@ public: template < typename T > class vec_base { public: - T x{}, y{}, z{}, w{}; + T x = T{0}; + T y = T{0}; + T z = T{0}; + T w = T{0}; constexpr vec_base() = default; constexpr explicit vec_base(T v); @@ -142,6 +148,10 @@ public: static constexpr size_t size = Size; + constexpr vec() = default; + constexpr vec(const vec&) = default; + constexpr vec& operator=(const vec&) = default; + void swap(vec& other) noexcept(is_nothrow_swappable_v); iterator begin() noexcept; @@ -210,8 +220,8 @@ public: using row_type = vec; row_type rows[2] = { - {1, 0}, - {0, 1}}; + row_type{T{1}, T{0}}, + row_type{T{0}, T{1}}}; constexpr mat_base() = default; constexpr explicit mat_base(T d); @@ -235,9 +245,9 @@ public: using row_type = vec; row_type rows[3] = { - {1, 0, 0}, - {0, 1, 0}, - {0, 0, 1}}; + row_type{T{1}, T{0}, T{0}}, + row_type{T{0}, T{1}, T{0}}, + row_type{T{0}, T{0}, T{1}}}; constexpr mat_base() = default; constexpr explicit mat_base(T d); @@ -267,10 +277,10 @@ public: using row_type = vec; row_type rows[4] = { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1}}; + row_type{T{1}, T{0}, T{0}, T{0}}, + row_type{T{0}, T{1}, T{0}, T{0}}, + row_type{T{0}, T{0}, T{1}, T{0}}, + row_type{T{0}, T{0}, T{0}, T{1}}}; constexpr mat_base() = default; constexpr explicit mat_base(T d); @@ -315,6 +325,10 @@ public: static constexpr size_t size = Size; + constexpr mat() = default; + constexpr mat(const mat&) = default; + constexpr mat& operator=(const mat&) = default; + void swap(mat& other) noexcept(is_nothrow_swappable_v); iterator begin() noexcept; @@ -377,8 +391,11 @@ using ptrdiff4x4_t = mat; template < typename T > class qua final { public: - vec v{0}; - T s{1}; + using imag_type = vec; + using real_type = T; + + imag_type v = imag_type{T{0}}; + real_type s = real_type{T{1}}; public: using self_type = qua; using component_type = T; diff --git a/headers/vmath.hpp/vmath_mat.hpp b/headers/vmath.hpp/vmath_mat.hpp index c176340..d6c377a 100644 --- a/headers/vmath.hpp/vmath_mat.hpp +++ b/headers/vmath.hpp/vmath_mat.hpp @@ -20,21 +20,22 @@ namespace vmath_hpp::detail class mat_base { public: using row_type = vec; + row_type rows[2] = { - {1, 0}, - {0, 1}}; + row_type{T{1}, T{0}}, + row_type{T{0}, T{1}}}; public: constexpr mat_base() = default; constexpr explicit mat_base(T d) : rows{ - row_type{d, 0}, - row_type{0, d}} {} + row_type{d, T{0}}, + row_type{T{0}, d}} {} constexpr explicit mat_base(const row_type& d) : rows{ - row_type{d[0], 0}, - row_type{0, d[1]}} {} + row_type{d[0], T{0}}, + row_type{T{0}, d[1]}} {} constexpr mat_base( T m11, T m12, @@ -65,24 +66,25 @@ namespace vmath_hpp::detail class mat_base { public: using row_type = vec; + row_type rows[3] = { - {1, 0, 0}, - {0, 1, 0}, - {0, 0, 1}}; + row_type{T{1}, T{0}, T{0}}, + row_type{T{0}, T{1}, T{0}}, + row_type{T{0}, T{0}, T{1}}}; public: constexpr mat_base() = default; constexpr explicit mat_base(T d) : rows{ - row_type{d, 0, 0}, - row_type{0, d, 0}, - row_type{0, 0, d}} {} + row_type{d, T{0}, T{0}}, + row_type{T{0}, d, T{0}}, + row_type{T{0}, T{0}, d}} {} constexpr explicit mat_base(const row_type& d) : rows{ - row_type{d[0], 0, 0}, - row_type{0, d[1], 0}, - row_type{0, 0, d[2]}} {} + row_type{d[0], T{0}, T{0}}, + row_type{T{0}, d[1], T{0}}, + row_type{T{0}, T{0}, d[2]}} {} constexpr mat_base( T m11, T m12, T m13, @@ -103,16 +105,16 @@ namespace vmath_hpp::detail const mat_base& m, const vec_base& v) : rows{ - row_type{m.rows[0], 0}, - row_type{m.rows[1], 0}, - row_type{v, 1}} {} + row_type{m.rows[0], T{0}}, + row_type{m.rows[1], T{0}}, + row_type{v, T{1}}} {} constexpr explicit mat_base( const mat_base& other) : rows{ - row_type{other.rows[0], 0}, - row_type{other.rows[1], 0}, - row_type{0, 0, 1}} {} + row_type{other.rows[0], T{0}}, + row_type{other.rows[1], T{0}}, + row_type{T{0}, T{0}, T{1}}} {} constexpr explicit mat_base( const mat_base& other) @@ -126,27 +128,28 @@ namespace vmath_hpp::detail class mat_base { public: using row_type = vec; + row_type rows[4] = { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {0, 0, 0, 1}}; + row_type{T{1}, T{0}, T{0}, T{0}}, + row_type{T{0}, T{1}, T{0}, T{0}}, + row_type{T{0}, T{0}, T{1}, T{0}}, + row_type{T{0}, T{0}, T{0}, T{1}}}; public: constexpr mat_base() = default; constexpr explicit mat_base(T d) : rows{ - row_type{d, 0, 0, 0}, - row_type{0, d, 0, 0}, - row_type{0, 0, d, 0}, - row_type{0, 0, 0, d}} {} + row_type{d, T{0}, T{0}, T{0}}, + row_type{T{0}, d, T{0}, T{0}}, + row_type{T{0}, T{0}, d, T{0}}, + row_type{T{0}, T{0}, T{0}, d}} {} constexpr explicit mat_base(const row_type& d) : rows{ - row_type{d[0], 0, 0, 0}, - row_type{0, d[1], 0, 0}, - row_type{0, 0, d[2], 0}, - row_type{0, 0, 0, d[3]}} {} + row_type{d[0], T{0}, T{0}, T{0}}, + row_type{T{0}, d[1], T{0}, T{0}}, + row_type{T{0}, T{0}, d[2], T{0}}, + row_type{T{0}, T{0}, T{0}, d[3]}} {} constexpr mat_base( T m11, T m12, T m13, T m14, @@ -170,26 +173,26 @@ namespace vmath_hpp::detail const mat_base& m, const vec_base& v) : rows{ - row_type{m.rows[0], 0}, - row_type{m.rows[1], 0}, - row_type{m.rows[2], 0}, - row_type{v, 1}} {} + row_type{m.rows[0], T{0}}, + row_type{m.rows[1], T{0}}, + row_type{m.rows[2], T{0}}, + row_type{v, T{1}}} {} constexpr explicit mat_base( const mat_base& other) : rows{ - row_type{other.rows[0], 0, 0}, - row_type{other.rows[1], 0, 0}, - row_type{0, 0, 1, 0}, - row_type{0, 0, 0, 1}} {} + row_type{other.rows[0], T{0}, T{0}}, + row_type{other.rows[1], T{0}, T{0}}, + row_type{T{0}, T{0}, T{1}, T{0}}, + row_type{T{0}, T{0}, T{0}, T{1}}} {} constexpr explicit mat_base( const mat_base& other) : rows{ - row_type{other.rows[0], 0}, - row_type{other.rows[1], 0}, - row_type{other.rows[2], 0}, - row_type{0, 0, 0, 1}} {} + row_type{other.rows[0], T{0}}, + row_type{other.rows[1], T{0}}, + row_type{other.rows[2], T{0}}, + row_type{T{0}, T{0}, T{0}, T{1}}} {} }; } @@ -253,14 +256,6 @@ namespace vmath_hpp return &rows[0]; } - [[nodiscard]] constexpr reference operator[](std::size_t index) noexcept { - return rows[index]; - } - - [[nodiscard]] constexpr const_reference operator[](std::size_t index) const noexcept { - return rows[index]; - } - [[nodiscard]] constexpr reference at(std::size_t index) { VMATH_HPP_THROW_IF(index >= size, std::out_of_range("mat::at")); return rows[index]; @@ -270,6 +265,14 @@ namespace vmath_hpp VMATH_HPP_THROW_IF(index >= size, std::out_of_range("mat::at")); return rows[index]; } + + [[nodiscard]] constexpr reference operator[](std::size_t index) noexcept { + return rows[index]; + } + + [[nodiscard]] constexpr const_reference operator[](std::size_t index) const noexcept { + return rows[index]; + } }; } diff --git a/headers/vmath.hpp/vmath_qua.hpp b/headers/vmath.hpp/vmath_qua.hpp index 7cced4b..9d955b8 100644 --- a/headers/vmath.hpp/vmath_qua.hpp +++ b/headers/vmath.hpp/vmath_qua.hpp @@ -16,8 +16,11 @@ namespace vmath_hpp template < typename T > class qua final { public: - vec v{0}; - T s{1}; + using imag_type = vec; + using real_type = T; + + imag_type v = imag_type{T{0}}; + real_type s = real_type{T{1}}; public: using self_type = qua; using component_type = T; @@ -85,6 +88,16 @@ namespace vmath_hpp return &(*this)[0]; } + [[nodiscard]] constexpr reference at(std::size_t index) { + VMATH_HPP_THROW_IF(index >= size, std::out_of_range("qua::at")); + return (*this)[index]; + } + + [[nodiscard]] constexpr const_reference at(std::size_t index) const { + VMATH_HPP_THROW_IF(index >= size, std::out_of_range("qua::at")); + return (*this)[index]; + } + [[nodiscard]] constexpr reference operator[](std::size_t index) noexcept { switch ( index ) { default: @@ -104,16 +117,6 @@ namespace vmath_hpp case 3: return s; } } - - [[nodiscard]] constexpr reference at(std::size_t index) { - VMATH_HPP_THROW_IF(index >= size, std::out_of_range("qua::at")); - return (*this)[index]; - } - - [[nodiscard]] constexpr const_reference at(std::size_t index) const { - VMATH_HPP_THROW_IF(index >= size, std::out_of_range("qua::at")); - return (*this)[index]; - } }; } diff --git a/headers/vmath.hpp/vmath_vec.hpp b/headers/vmath.hpp/vmath_vec.hpp index ccad622..36a6f13 100644 --- a/headers/vmath.hpp/vmath_vec.hpp +++ b/headers/vmath.hpp/vmath_vec.hpp @@ -16,7 +16,8 @@ namespace vmath_hpp::detail template < typename T > class vec_base { public: - T x{}, y{}; + T x = T{0}; + T y = T{0}; public: constexpr vec_base() = default; @@ -52,7 +53,9 @@ namespace vmath_hpp::detail template < typename T > class vec_base { public: - T x{}, y{}, z{}; + T x = T{0}; + T y = T{0}; + T z = T{0}; public: constexpr vec_base() = default; @@ -93,7 +96,10 @@ namespace vmath_hpp::detail template < typename T > class vec_base { public: - T x{}, y{}, z{}, w{}; + T x = T{0}; + T y = T{0}; + T z = T{0}; + T w = T{0}; public: constexpr vec_base() = default; From 8e971073afe59f4d6a1731675a58832469474bc4 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 21 Feb 2021 01:09:25 +0700 Subject: [PATCH 04/15] ext funcs non-arithmetic T support --- README.md | 2 + headers/vmath.hpp/vmath_ext.hpp | 341 ++++++++++++++++++-------------- headers/vmath.hpp/vmath_fun.hpp | 24 +-- untests/vmath_ext_tests.cpp | 2 + untests/vmath_tests.hpp | 2 +- 5 files changed, 205 insertions(+), 166 deletions(-) diff --git a/README.md b/README.md index e4c5385..bb08b23 100644 --- a/README.md +++ b/README.md @@ -1556,6 +1556,8 @@ template < typename T > inline constexpr mat unit4x4; template < typename T > inline constexpr mat identity2x2; template < typename T > inline constexpr mat identity3x3; template < typename T > inline constexpr mat identity4x4; + +template < typename T > inline constexpr qua qidentity; ``` ### Cast diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index a80cfe4..c462e90 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -19,37 +19,72 @@ namespace vmath_hpp { - template < typename T > inline constexpr vec zero2{0, 0}; - template < typename T > inline constexpr vec zero3{0, 0, 0}; - template < typename T > inline constexpr vec zero4{0, 0, 0, 0}; + template < typename T > inline constexpr vec zero2{T{0}, T{0}}; + template < typename T > inline constexpr vec zero3{T{0}, T{0}, T{0}}; + template < typename T > inline constexpr vec zero4{T{0}, T{0}, T{0}, T{0}}; - template < typename T > inline constexpr vec unit2{1, 1}; - template < typename T > inline constexpr vec unit3{1, 1, 1}; - template < typename T > inline constexpr vec unit4{1, 1, 1, 1}; + template < typename T > inline constexpr vec unit2{T{1}, T{1}}; + template < typename T > inline constexpr vec unit3{T{1}, T{1}, T{1}}; + template < typename T > inline constexpr vec unit4{T{1}, T{1}, T{1}, T{1}}; - template < typename T > inline constexpr vec unit2_x{1, 0}; - template < typename T > inline constexpr vec unit2_y{0, 1}; + template < typename T > inline constexpr vec unit2_x{T{1}, T{0}}; + template < typename T > inline constexpr vec unit2_y{T{0}, T{1}}; - template < typename T > inline constexpr vec unit3_x{1, 0, 0}; - template < typename T > inline constexpr vec unit3_y{0, 1, 0}; - template < typename T > inline constexpr vec unit3_z{0, 0, 1}; + template < typename T > inline constexpr vec unit3_x{T{1}, T{0}, T{0}}; + template < typename T > inline constexpr vec unit3_y{T{0}, T{1}, T{0}}; + template < typename T > inline constexpr vec unit3_z{T{0}, T{0}, T{1}}; - template < typename T > inline constexpr vec unit4_x{1, 0, 0, 0}; - template < typename T > inline constexpr vec unit4_y{0, 1, 0, 0}; - template < typename T > inline constexpr vec unit4_z{0, 0, 1, 0}; - template < typename T > inline constexpr vec unit4_w{0, 0, 0, 1}; + template < typename T > inline constexpr vec unit4_x{T{1}, T{0}, T{0}, T{0}}; + template < typename T > inline constexpr vec unit4_y{T{0}, T{1}, T{0}, T{0}}; + template < typename T > inline constexpr vec unit4_z{T{0}, T{0}, T{1}, T{0}}; + template < typename T > inline constexpr vec unit4_w{T{0}, T{0}, T{0}, T{1}}; - template < typename T > inline constexpr mat zero2x2{0, 0, 0, 0}; - template < typename T > inline constexpr mat zero3x3{0, 0, 0, 0, 0, 0, 0, 0, 0}; - template < typename T > inline constexpr mat zero4x4{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + template < typename T > inline constexpr mat zero2x2{ + T{0}, T{0}, + T{0}, T{0}}; - template < typename T > inline constexpr mat unit2x2{1, 1, 1, 1}; - template < typename T > inline constexpr mat unit3x3{1, 1, 1, 1, 1, 1, 1, 1, 1}; - template < typename T > inline constexpr mat unit4x4{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; + template < typename T > inline constexpr mat zero3x3{ + T{0}, T{0}, T{0}, + T{0}, T{0}, T{0}, + T{0}, T{0}, T{0}}; - template < typename T > inline constexpr mat identity2x2{1, 0, 0, 1}; - template < typename T > inline constexpr mat identity3x3{1, 0, 0, 0, 1, 0, 0, 0, 1}; - template < typename T > inline constexpr mat identity4x4{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}; + template < typename T > inline constexpr mat zero4x4{ + T{0}, T{0}, T{0}, T{0}, + T{0}, T{0}, T{0}, T{0}, + T{0}, T{0}, T{0}, T{0}, + T{0}, T{0}, T{0}, T{0}}; + + template < typename T > inline constexpr mat unit2x2{ + T{1}, T{1}, + T{1}, T{1}}; + + template < typename T > inline constexpr mat unit3x3{ + T{1}, T{1}, T{1}, + T{1}, T{1}, T{1}, + T{1}, T{1}, T{1}}; + + template < typename T > inline constexpr mat unit4x4{ + T{1}, T{1}, T{1}, T{1}, + T{1}, T{1}, T{1}, T{1}, + T{1}, T{1}, T{1}, T{1}, + T{1}, T{1}, T{1}, T{1}}; + + template < typename T > inline constexpr mat identity2x2{ + T{1}, T{0}, + T{0}, T{1}}; + + template < typename T > inline constexpr mat identity3x3{ + T{1}, T{0}, T{0}, + T{0}, T{1}, T{0}, + T{0}, T{0}, T{1}}; + + template < typename T > inline constexpr mat identity4x4{ + T{1}, T{0}, T{0}, T{0}, + T{0}, T{1}, T{0}, T{0}, + T{0}, T{0}, T{1}, T{0}, + T{0}, T{0}, T{0}, T{1}}; + + template < typename T > inline constexpr qua qidentity{T{0}, T{0}, T{0}, T{1}}; } // @@ -235,10 +270,10 @@ namespace vmath_hpp /// https://en.wikipedia.org/wiki/Translation_(geometry) return { - {1, 0, 0, 0}, - {0, 1, 0, 0}, - {0, 0, 1, 0}, - {x, y, z, 1}}; + {T{1}, T{0}, T{0}, T{0}}, + {T{0}, T{1}, T{0}, T{0}}, + {T{0}, T{0}, T{1}, T{0}}, + { x, y, z, T{1}}}; } template < typename T > @@ -265,9 +300,9 @@ namespace vmath_hpp const auto [qv, qs] = normalize(q); - const T x2 = qv.x * T(2); - const T y2 = qv.y * T(2); - const T z2 = qv.z * T(2); + const T x2 = qv.x * T{2}; + const T y2 = qv.y * T{2}; + const T z2 = qv.z * T{2}; const T sx2 = qs * x2; const T sy2 = qs * y2; @@ -282,10 +317,10 @@ namespace vmath_hpp const T zz2 = qv.z * z2; return { - T(1) - (yy2 + zz2), (xy2 + sz2), (xz2 - sy2), 0, - (xy2 - sz2), T(1) - (xx2 + zz2), (yz2 + sx2), 0, - (xz2 + sy2), (yz2 - sx2), T(1) - (xx2 + yy2), 0, - 0, 0, 0, 1}; + T{1} - (yy2 + zz2), (xy2 + sz2), (xz2 - sy2), T{0}, + (xy2 - sz2), T{1} - (xx2 + zz2), (yz2 + sx2), T{0}, + (xz2 + sy2), (yz2 - sx2), T{1} - (xx2 + yy2), T{0}, + T{0}, T{0}, T{0}, T{1}}; } template < typename T > @@ -309,7 +344,7 @@ namespace vmath_hpp const T ys = y * s; const T zs = z * s; - const T ic = T(1) - c; + const T ic = T{1} - c; const T xxm = xx * ic; const T yym = yy * ic; @@ -320,10 +355,10 @@ namespace vmath_hpp const T yzm = y * z * ic; return { - xxm + c, xym + zs, xzm - ys, 0, - xym - zs, yym + c, yzm + xs, 0, - xzm + ys, yzm - xs, zzm + c, 0, - 0, 0, 0, 1}; + xxm + c, xym + zs, xzm - ys, T{0}, + xym - zs, yym + c, yzm + xs, T{0}, + xzm + ys, yzm - xs, zzm + c, T{0}, + T{0}, T{0}, T{0}, T{1}}; } template < typename T > @@ -339,10 +374,10 @@ namespace vmath_hpp const auto [s, c] = sincos(angle); return { - 1, 0, 0, 0, - 0, c, s, 0, - 0, -s, c, 0, - 0, 0, 0, 1}; + T{1}, T{0}, T{0}, T{0}, + T{0}, c, s, T{0}, + T{0}, -s, c, T{0}, + T{0}, T{0}, T{0}, T{1}}; } template < typename T > @@ -358,10 +393,10 @@ namespace vmath_hpp const auto [s, c] = sincos(angle); return { - c, 0, -s, 0, - 0, 1, 0, 0, - s, 0, c, 0, - 0, 0, 0, 1}; + c, T{0}, -s, T{0}, + T{0}, T{1}, T{0}, T{0}, + s, T{0}, c, T{0}, + T{0}, T{0}, T{0}, T{1}}; } template < typename T > @@ -377,10 +412,10 @@ namespace vmath_hpp const auto [s, c] = sincos(angle); return { - c, s, 0, 0, - -s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1}; + c, s, T{0}, T{0}, + -s, c, T{0}, T{0}, + T{0}, T{0}, T{1}, T{0}, + T{0}, T{0}, T{0}, T{1}}; } template < typename T > @@ -396,10 +431,10 @@ namespace vmath_hpp /// https://en.wikipedia.org/wiki/Scaling_(geometry) return { - {x, 0, 0, 0}, - {0, y, 0, 0}, - {0, 0, z, 0}, - {0, 0, 0, 1}}; + { x, T{0}, T{0}, T{0}}, + {T{0}, y, T{0}, T{0}}, + {T{0}, T{0}, z, T{0}}, + {T{0}, T{0}, T{0}, T{1}}}; } template < typename T > @@ -433,10 +468,10 @@ namespace vmath_hpp const T dz = dot(az, eye); return { - ax.x, ay.x, az.x, 0, - ax.y, ay.y, az.y, 0, - ax.z, ay.z, az.z, 0, - -dx, -dy, -dz, 1}; + ax.x, ay.x, az.x, T{0}, + ax.y, ay.y, az.y, T{0}, + ax.z, ay.z, az.z, T{0}, + -dx, -dy, -dz, T{1}}; } template < typename T > @@ -453,10 +488,10 @@ namespace vmath_hpp const T dz = dot(az, eye); return { - ax.x, ay.x, az.x, 0, - ax.y, ay.y, az.y, 0, - ax.z, ay.z, az.z, 0, - -dx, -dy, -dz, 1}; + ax.x, ay.x, az.x, T{0}, + ax.y, ay.y, az.y, T{0}, + ax.z, ay.z, az.z, T{0}, + -dx, -dy, -dz, T{1}}; } } @@ -474,9 +509,9 @@ namespace vmath_hpp /// https://en.wikipedia.org/wiki/Translation_(geometry) return { - {1, 0, 0}, - {0, 1, 0}, - {x, y, 1}}; + {T{1}, T{0}, T{0}}, + {T{0}, T{1}, T{0}}, + { x, y, T{1}}}; } template < typename T > @@ -504,9 +539,9 @@ namespace vmath_hpp const auto [s, c] = sincos(angle); return { - c, s, 0, - -s, c, 0, - 0, 0, 1}; + c, s, T{0}, + -s, c, T{0}, + T{0}, T{0}, T{1}}; } template < typename T > @@ -522,9 +557,9 @@ namespace vmath_hpp /// https://en.wikipedia.org/wiki/Scaling_(geometry) return { - {x, 0, 0}, - {0, y, 0}, - {0, 0, 1}}; + { x, T{0}, T{0}}, + {T{0}, y, T{0}}, + {T{0}, T{0}, T{1}}}; } template < typename T > @@ -550,9 +585,9 @@ namespace vmath_hpp /// https://en.wikipedia.org/wiki/Shear_matrix return { - {1, y, 0}, - {x, 1, 0}, - {0, 0, 1}}; + {T{1}, y, T{0}}, + { x, T{1}, T{0}}, + {T{0}, T{0}, T{1}}}; } template < typename T > @@ -576,9 +611,9 @@ namespace vmath_hpp /// https://en.wikipedia.org/wiki/Shear_matrix return { - {1, 0, 0}, - {x, 1, 0}, - {0, 0, 1}}; + {T{1}, T{0}, T{0}}, + { x, T{1}, T{0}}, + {T{0}, T{0}, T{1}}}; } template < typename T > @@ -592,9 +627,9 @@ namespace vmath_hpp /// https://en.wikipedia.org/wiki/Shear_matrix return { - {1, y, 0}, - {0, 1, 0}, - {0, 0, 1}}; + {T{1}, y, T{0}}, + {T{0}, T{1}, T{0}}, + {T{0}, T{0}, T{1}}}; } template < typename T > @@ -620,16 +655,16 @@ namespace vmath_hpp const T rheight = rcp(height); const T frange = rcp(zfar - znear); - const T sx = T(2) * rwidth; - const T sy = T(2) * rheight; + const T sx = T{2} * rwidth; + const T sy = T{2} * rheight; const T sz = frange; const T tz = -frange * znear; return { - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, 0, - 0, 0, tz, 1}; + sx, T{0}, T{0}, T{0}, + T{0}, sy, T{0}, T{0}, + T{0}, T{0}, sz, T{0}, + T{0}, T{0}, tz, T{1}}; } template < typename T > @@ -641,16 +676,16 @@ namespace vmath_hpp const T rheight = rcp(height); const T frange = rcp(znear - zfar); - const T sx = T(2) * rwidth; - const T sy = T(2) * rheight; + const T sx = T{2} * rwidth; + const T sy = T{2} * rheight; const T sz = frange; const T tz = frange * znear; return { - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, 0, - 0, 0, tz, 1}; + sx, T{0}, T{0}, T{0}, + T{0}, sy, T{0}, T{0}, + T{0}, T{0}, sz, T{0}, + T{0}, T{0}, tz, T{1}}; } template < typename T > @@ -663,10 +698,10 @@ namespace vmath_hpp const T frange = rcp(zfar - znear); return { - T(2) * rwidth, 0, 0, 0, - 0, T(2) * rheight, 0, 0, - 0, 0, frange, 0, - -(left + right) * rwidth, -(top + bottom) * rheight, -frange * znear, 1}; + T{2} * rwidth, T{0}, T{0}, T{0}, + T{0}, T{2} * rheight, T{0}, T{0}, + T{0}, T{0}, frange, T{0}, + -(left + right) * rwidth, -(top + bottom) * rheight, -frange * znear, T{1}}; } template < typename T > @@ -679,10 +714,10 @@ namespace vmath_hpp const T frange = rcp(znear - zfar); return { - T(2) * rwidth, 0, 0, 0, - 0, T(2) * rheight, 0, 0, - 0, 0, frange, 0, - -(left + right) * rwidth, -(top + bottom) * rheight, frange * znear, 1}; + T{2} * rwidth, T{0}, T{0}, T{0}, + T{0}, T{2} * rheight, T{0}, T{0}, + T{0}, T{0}, frange, T{0}, + -(left + right) * rwidth, -(top + bottom) * rheight, frange * znear, T{1}}; } // perspective @@ -692,16 +727,16 @@ namespace vmath_hpp /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivelh - const T sx = T(2) * znear * rcp(width); - const T sy = T(2) * znear * rcp(height); + const T sx = T{2} * znear * rcp(width); + const T sy = T{2} * znear * rcp(height); const T sz = zfar * rcp(zfar - znear); const T tz = (znear * zfar) * rcp(znear - zfar); return { - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, 1, - 0, 0, tz, 0}; + T{sx}, T{0}, T{0}, T{0}, + T{0}, T{sy}, T{0}, T{0}, + T{0}, T{0}, T{sz}, T{1}, + T{0}, T{0}, T{tz}, T{0}}; } template < typename T > @@ -709,16 +744,16 @@ namespace vmath_hpp /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiverh - const T sx = T(2) * znear * rcp(width); - const T sy = T(2) * znear * rcp(height); + const T sx = T{2} * znear * rcp(width); + const T sy = T{2} * znear * rcp(height); const T sz = zfar * rcp(znear - zfar); const T tz = (znear * zfar) * rcp(znear - zfar); return { - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, -1, - 0, 0, tz, 0}; + sx, T{0}, T{0}, T{0}, + T{0}, sy, T{0}, T{0}, + T{0}, T{0}, sz, -T{1}, + T{0}, T{0}, tz, T{0}}; } template < typename T > @@ -726,16 +761,16 @@ namespace vmath_hpp /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiveoffcenterlh - const T znear2 = T(2) * znear; + const T znear2 = T{2} * znear; const T rwidth = rcp(right - left); const T rheight = rcp(top - bottom); const T frange = zfar * rcp(zfar - znear); return { - znear2 * rwidth, 0, 0, 0, - 0, znear2 * rheight, 0, 0, - -(left + right) * rwidth, -(top + bottom) * rheight, frange, 1, - 0, 0, -frange * znear, 0}; + znear2 * rwidth, T{0}, T{0}, T{0}, + T{0}, znear2 * rheight, T{0}, T{0}, + -(left + right) * rwidth, -(top + bottom) * rheight, frange, T{1}, + T{0}, T{0}, -frange * znear, T{0}}; } template < typename T > @@ -743,16 +778,16 @@ namespace vmath_hpp /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiveoffcenterrh - const T znear2 = T(2) * znear; + const T znear2 = T{2} * znear; const T rwidth = rcp(right - left); const T rheight = rcp(top - bottom); const T frange = zfar * rcp(znear - zfar); return { - znear2 * rwidth, 0, 0, 0, - 0, znear2 * rheight, 0, 0, - (left + right) * rwidth, (top + bottom) * rheight, frange, -1, - 0, 0, frange * znear, 0}; + znear2 * rwidth, T{0}, T{0}, T{0}, + T{0}, znear2 * rheight, T{0}, T{0}, + (left + right) * rwidth, (top + bottom) * rheight, frange, -T{1}, + T{0}, T{0}, frange * znear, T{0}}; } template < typename T > @@ -760,16 +795,16 @@ namespace vmath_hpp /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovlh - const T sy = rcp(tan(fovy * T(0.5))); + const T sy = rcp(tan(fovy * T{0.5})); const T sx = sy * rcp(aspect); const T sz = zfar * rcp(zfar - znear); const T tz = (znear * zfar) * rcp(znear - zfar); return { - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, 1, - 0, 0, tz, 0}; + sx, T{0}, T{0}, T{0}, + T{0}, sy, T{0}, T{0}, + T{0}, T{0}, sz, T{1}, + T{0}, T{0}, tz, T{0}}; } template < typename T > @@ -777,15 +812,15 @@ namespace vmath_hpp /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh - const T sy = rcp(tan(fovy * T(0.5))); + const T sy = rcp(tan(fovy * T{0.5})); const T sx = sy * rcp(aspect); const T sz = zfar * rcp(znear - zfar); const T tz = (znear * zfar) * rcp(znear - zfar); return { - sx, 0, 0, 0, - 0, sy, 0, 0, - 0, 0, sz, -1, - 0, 0, tz, 0}; + sx, T{0}, T{0}, T{0}, + T{0}, sy, T{0}, T{0}, + T{0}, T{0}, sz, -T{1}, + T{0}, T{0}, tz, T{0}}; } } @@ -800,7 +835,7 @@ namespace vmath_hpp template < typename T, std::size_t Size > [[nodiscard]] T angle(const vec& x, const vec& y) { const T rs = rsqrt(length2(x) * length2(y)); - return acos(clamp(dot(x, y) * rs, T(-1), T(1))); + return acos(clamp(dot(x, y) * rs, -T{1}, T{1})); } // rotate @@ -866,17 +901,17 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ - auto xyzw = T(0.5) * sqrt(max(T(0), vec{ - T(1) + m[0][0] - m[1][1] - m[2][2], - T(1) - m[0][0] + m[1][1] - m[2][2], - T(1) - m[0][0] - m[1][1] + m[2][2], - T(1) + m[0][0] + m[1][1] + m[2][2]})); + auto xyzw = T{0.5} * sqrt(max(T{0}, vec{ + T{1} + m[0][0] - m[1][1] - m[2][2], + T{1} - m[0][0] + m[1][1] - m[2][2], + T{1} - m[0][0] - m[1][1] + m[2][2], + T{1} + m[0][0] + m[1][1] + m[2][2]})); return qua(copysign(xyzw, { m[1][2] - m[2][1], m[2][0] - m[0][2], m[0][1] - m[1][0], - T(1)})); + T{1}})); } template < typename T > @@ -892,10 +927,10 @@ namespace vmath_hpp const T n = sqrt(length2(from) * length2(to)); const T s = dot(from, to) + n; - if ( s < T(0.000001) * n ) { - return abs(from.x) > abs(from.z) - ? normalize(qua{vec{-from.y, from.x, T(0)}, T(0)}) - : normalize(qua{vec{T(0), -from.z, from.y}, T(0)}); + if ( s < T{0.000001} * n ) { + return abs(from.z) < abs(from.x) + ? normalize(qua{vec{-from.y, from.x, T{0}}, T{0}}) + : normalize(qua{vec{T{0}, -from.z, from.y}, T{0}}); } return normalize(qua{cross(from, to), s}); @@ -911,10 +946,10 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ - const auto [s, c] = sincos(angle * T(0.5)); + const auto [s, c] = sincos(angle * T{0.5}); const auto [x, y, z] = normalize(axis); - return {vec{x,y,z} * s, c}; + return {vec{x, y, z} * s, c}; } template < typename T > @@ -927,9 +962,9 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ - const auto [s, c] = sincos(angle * T(0.5)); + const auto [s, c] = sincos(angle * T{0.5}); - return {s, T(0), T(0), c}; + return {vec{s, T{0}, T{0}}, c}; } template < typename T > @@ -942,9 +977,9 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ - const auto [s, c] = sincos(angle * T(0.5)); + const auto [s, c] = sincos(angle * T{0.5}); - return {T(0), s, T(0), c}; + return {vec{T{0}, s, T{0}}, c}; } template < typename T > @@ -957,9 +992,9 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ - const auto [s, c] = sincos(angle * T(0.5)); + const auto [s, c] = sincos(angle * T{0.5}); - return {T(0), T(0), s, c}; + return {vec{T{0}, T{0}, s}, c}; } template < typename T > diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index 3701c02..aa6b37f 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -17,7 +17,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr abs(T x) noexcept { - return x >= T(0) ? x : -x; + return x < T{0} ? -x : x; } template < typename T > @@ -35,13 +35,13 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr sign(T x) noexcept { - return static_cast((T(0) < x) - (x < T(0))); + return static_cast((T{0} < x) - (x < T{0})); } template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr rcp(T x) noexcept { - return T(1) / x; + return T{1} / x; } template < typename T > @@ -107,13 +107,13 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr saturate(T x) noexcept { - return clamp(x, T(0), T(1)); + return clamp(x, T{0}, T{1}); } template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr lerp(T x, T y, T a) noexcept { - return x * (T(1) - a) + y * a; + return x * (T{1} - a) + y * a; } template < typename T > @@ -125,14 +125,14 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr step(T edge, T x) noexcept { - return x < edge ? T(0) : T(1); + return x < edge ? T{0} : T{1}; } template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr smoothstep(T edge0, T edge1, T x) noexcept { - const T t = clamp((x - edge0) * rcp(edge1 - edge0), T(0), T(1)); - return t * t * (T(3) - T(2) * t); + const T t = clamp((x - edge0) * rcp(edge1 - edge0), T{0}, T{1}); + return t * t * (T{3} - T{2} * t); } template < typename T > @@ -151,13 +151,13 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr radians(T degrees) noexcept { - return degrees * T(0.01745329251994329576923690768489); + return degrees * T{0.01745329251994329576923690768489}; } template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr degrees(T radians) noexcept { - return radians * T(57.295779513082320876798154814105); + return radians * T{57.295779513082320876798154814105}; } template < typename T > @@ -369,7 +369,7 @@ namespace vmath_hpp /// REFERENCE: /// http://www.realtimecollisiondetection.net/pubs/Tolerances const T epsilon = std::numeric_limits::epsilon(); - return abs(x - y) <= epsilon * max(max(T(1), abs(x)), abs(y)); + return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y)); } else { return x == y; } @@ -381,7 +381,7 @@ namespace vmath_hpp if constexpr ( std::is_floating_point_v ) { /// REFERENCE: /// http://www.realtimecollisiondetection.net/pubs/Tolerances - return abs(x - y) <= epsilon * max(max(T(1), abs(x)), abs(y)); + return abs(x - y) <= epsilon * max(max(T{1}, abs(x)), abs(y)); } else { return abs(x - y) <= epsilon; } diff --git a/untests/vmath_ext_tests.cpp b/untests/vmath_ext_tests.cpp index bfeb4ce..55b2f58 100644 --- a/untests/vmath_ext_tests.cpp +++ b/untests/vmath_ext_tests.cpp @@ -52,6 +52,8 @@ TEST_CASE("vmath/ext/units") { STATIC_CHECK(identity2x2 == int2x2()); STATIC_CHECK(identity3x3 == int3x3()); STATIC_CHECK(identity4x4 == int4x4()); + + STATIC_CHECK(qidentity == qfloat()); } TEST_CASE("vmath/ext/hash") { diff --git a/untests/vmath_tests.hpp b/untests/vmath_tests.hpp index 7b56cf7..558ecd0 100644 --- a/untests/vmath_tests.hpp +++ b/untests/vmath_tests.hpp @@ -13,7 +13,7 @@ namespace vmath_tests template < typename T > struct uapprox_base { - T epsilon = T(10) * std::numeric_limits::epsilon(); + T epsilon = T{10} * std::numeric_limits::epsilon(); }; template < typename T > From 2a19b789eb761bfc85bf3b92fc205c0f9df11433 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 21 Feb 2021 01:27:12 +0700 Subject: [PATCH 05/15] operators non-arithmetic T support --- README.md | 144 ++++++++++++++-------------- headers/vmath.hpp/vmath_mat_fun.hpp | 62 ++++++------ headers/vmath.hpp/vmath_qua_fun.hpp | 24 ++--- headers/vmath.hpp/vmath_vec_fun.hpp | 62 ++++++------ 4 files changed, 146 insertions(+), 146 deletions(-) diff --git a/README.md b/README.md index bb08b23..43cfac7 100644 --- a/README.md +++ b/README.md @@ -460,33 +460,33 @@ using qdouble = qua; // +operator template < typename T, size_t Size > -constexpr vec operator+(const vec& xs); +constexpr auto operator+(const vec& xs); // -operator template < typename T, size_t Size > -constexpr vec operator-(const vec& xs); +constexpr auto operator-(const vec& xs); // ~operator template < typename T, size_t Size > -constexpr vec operator~(const vec& xs); +constexpr auto operator~(const vec& xs); // !operator template < typename T, size_t Size > -constexpr vec operator!(const vec& xs); +constexpr auto operator!(const vec& xs); // operator+ template < typename T, size_t Size > -constexpr vec operator+(const vec& xs, T y); +constexpr auto operator+(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec operator+(T x, const vec& ys); +constexpr auto operator+(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec operator+(const vec& xs, const vec& ys); +constexpr auto operator+(const vec& xs, const vec& ys); // operator+= @@ -499,13 +499,13 @@ constexpr vec& operator+=(vec& xs, const vec& ys); // operator- template < typename T, size_t Size > -constexpr vec operator-(const vec& xs, T y); +constexpr auto operator-(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec operator-(T x, const vec& ys); +constexpr auto operator-(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec operator-(const vec& xs, const vec& ys); +constexpr auto operator-(const vec& xs, const vec& ys); // operator-= @@ -518,13 +518,13 @@ constexpr vec& operator-=(vec& xs, const vec& ys); // operator* template < typename T, size_t Size > -constexpr vec operator*(const vec& xs, T y); +constexpr auto operator*(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec operator*(T x, const vec& ys); +constexpr auto operator*(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec operator*(const vec& xs, const vec& ys); +constexpr auto operator*(const vec& xs, const vec& ys); // operator*= @@ -537,13 +537,13 @@ constexpr vec& operator*=(vec& xs, const vec& ys); // operator/ template < typename T, size_t Size > -constexpr vec operator/(const vec& xs, T y); +constexpr auto operator/(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec operator/(T x, const vec& ys); +constexpr auto operator/(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec operator/(const vec& xs, const vec& ys); +constexpr auto operator/(const vec& xs, const vec& ys); // operator/= @@ -556,13 +556,13 @@ constexpr vec& operator/=(vec& xs, const vec& ys); // operator& template < typename T, size_t Size > -constexpr vec operator&(const vec& xs, T y); +constexpr auto operator&(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec operator&(T x, const vec& ys); +constexpr auto operator&(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec operator&(const vec& xs, const vec& ys); +constexpr auto operator&(const vec& xs, const vec& ys); // operator&= @@ -575,13 +575,13 @@ constexpr vec& operator&=(vec& xs, const vec& ys); // operator| template < typename T, size_t Size > -constexpr vec operator|(const vec& xs, T y); +constexpr auto operator|(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec operator|(T x, const vec& ys); +constexpr auto operator|(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec operator|(const vec& xs, const vec& ys); +constexpr auto operator|(const vec& xs, const vec& ys); // operator|= @@ -594,13 +594,13 @@ constexpr vec& operator|=(vec& xs, const vec& ys); // operator^ template < typename T, size_t Size > -constexpr vec operator^(const vec& xs, T y); +constexpr auto operator^(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec operator^(T x, const vec& ys); +constexpr auto operator^(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec operator^(const vec& xs, const vec& ys); +constexpr auto operator^(const vec& xs, const vec& ys); // operator^= @@ -613,24 +613,24 @@ constexpr vec& operator^=(vec& xs, const vec& ys); // operator&& template < typename T, size_t Size > -constexpr vec operator&&(const vec& xs, T y); +constexpr auto operator&&(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec operator&&(T x, const vec& ys); +constexpr auto operator&&(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec operator&&(const vec& xs, const vec& ys); +constexpr auto operator&&(const vec& xs, const vec& ys); // operator|| template < typename T, size_t Size > -constexpr vec operator||(const vec& xs, T y); +constexpr auto operator||(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec operator||(T x, const vec& ys); +constexpr auto operator||(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec operator||(const vec& xs, const vec& ys); +constexpr auto operator||(const vec& xs, const vec& ys); // operator== @@ -654,33 +654,33 @@ constexpr bool operator<(const vec& xs, const vec& ys); // +operator template < typename T, size_t Size > -constexpr mat operator+(const mat& xs); +constexpr auto operator+(const mat& xs); // -operator template < typename T, size_t Size > -constexpr mat operator-(const mat& xs); +constexpr auto operator-(const mat& xs); // ~operator template < typename T, size_t Size > -constexpr mat operator~(const mat& xs); +constexpr auto operator~(const mat& xs); // !operator template < typename T, size_t Size > -constexpr mat operator!(const mat& xs); +constexpr auto operator!(const mat& xs); // operator+ template < typename T, size_t Size > -constexpr mat operator+(const mat& xs, T y); +constexpr auto operator+(const mat& xs, T y); template < typename T, size_t Size > -constexpr mat operator+(T x, const mat& ys); +constexpr auto operator+(T x, const mat& ys); template < typename T, size_t Size > -constexpr mat operator+(const mat& xs, const mat& ys); +constexpr auto operator+(const mat& xs, const mat& ys); // operator+= @@ -693,13 +693,13 @@ constexpr mat& operator+=(mat& xs, const mat& ys); // operator- template < typename T, size_t Size > -constexpr mat operator-(const mat& xs, T y); +constexpr auto operator-(const mat& xs, T y); template < typename T, size_t Size > -constexpr mat operator-(T x, const mat& ys); +constexpr auto operator-(T x, const mat& ys); template < typename T, size_t Size > -constexpr mat operator-(const mat& xs, const mat& ys); +constexpr auto operator-(const mat& xs, const mat& ys); // operator-= @@ -712,16 +712,16 @@ constexpr mat& operator-=(mat& xs, const mat& ys); // operator* template < typename T, size_t Size > -constexpr mat operator*(const mat& xs, T y); +constexpr auto operator*(const mat& xs, T y); template < typename T, size_t Size > -constexpr mat operator*(T x, const mat& ys); +constexpr auto operator*(T x, const mat& ys); template < typename T, size_t Size > -constexpr vec operator*(const vec& xs, const mat& ys); +constexpr auto operator*(const vec& xs, const mat& ys); template < typename T, size_t Size > -constexpr mat operator*(const mat& xs, const mat& ys); +constexpr auto operator*(const mat& xs, const mat& ys); // operator*= @@ -737,10 +737,10 @@ constexpr mat& operator*=(mat& xs, const mat& ys); // operator/ template < typename T, size_t Size > -constexpr mat operator/(const mat& xs, T y); +constexpr auto operator/(const mat& xs, T y); template < typename T, size_t Size > -constexpr mat operator/(T x, const mat& ys); +constexpr auto operator/(T x, const mat& ys); // operator/= @@ -750,13 +750,13 @@ constexpr mat& operator/=(mat& xs, T y); // operator& template < typename T, size_t Size > -constexpr mat operator&(const mat& xs, T y); +constexpr auto operator&(const mat& xs, T y); template < typename T, size_t Size > -constexpr mat operator&(T x, const mat& ys); +constexpr auto operator&(T x, const mat& ys); template < typename T, size_t Size > -constexpr mat operator&(const mat& xs, const mat& ys); +constexpr auto operator&(const mat& xs, const mat& ys); // operator&= @@ -769,13 +769,13 @@ constexpr mat& operator&=(mat& xs, const mat& ys); // operator| template < typename T, size_t Size > -constexpr mat operator|(const mat& xs, T y); +constexpr auto operator|(const mat& xs, T y); template < typename T, size_t Size > -constexpr mat operator|(T x, const mat& ys); +constexpr auto operator|(T x, const mat& ys); template < typename T, size_t Size > -constexpr mat operator|(const mat& xs, const mat& ys); +constexpr auto operator|(const mat& xs, const mat& ys); // operator|= @@ -788,13 +788,13 @@ constexpr mat& operator|=(mat& xs, const mat& ys); // operator^ template < typename T, size_t Size > -constexpr mat operator^(const mat& xs, T y); +constexpr auto operator^(const mat& xs, T y); template < typename T, size_t Size > -constexpr mat operator^(T x, const mat& ys); +constexpr auto operator^(T x, const mat& ys); template < typename T, size_t Size > -constexpr mat operator^(const mat& xs, const mat& ys); +constexpr auto operator^(const mat& xs, const mat& ys); // operator^= @@ -807,24 +807,24 @@ constexpr mat& operator^=(mat& xs, const mat& ys); // operator&& template < typename T, size_t Size > -constexpr mat operator&&(const mat& xs, T y); +constexpr auto operator&&(const mat& xs, T y); template < typename T, size_t Size > -constexpr mat operator&&(T x, const mat& ys); +constexpr auto operator&&(T x, const mat& ys); template < typename T, size_t Size > -constexpr mat operator&&(const mat& xs, const mat& ys); +constexpr auto operator&&(const mat& xs, const mat& ys); // operator|| template < typename T, size_t Size > -constexpr mat operator||(const mat& xs, T y); +constexpr auto operator||(const mat& xs, T y); template < typename T, size_t Size > -constexpr mat operator||(T x, const mat& ys); +constexpr auto operator||(T x, const mat& ys); template < typename T, size_t Size > -constexpr mat operator||(const mat& xs, const mat& ys); +constexpr auto operator||(const mat& xs, const mat& ys); // operator== @@ -848,17 +848,17 @@ constexpr bool operator<(const mat& xs, const mat& ys); // +operator template < typename T > -constexpr qua operator+(const qua& xs); +constexpr auto operator+(const qua& xs); // -operator template < typename T > -constexpr qua operator-(const qua& xs); +constexpr auto operator-(const qua& xs); // operator+ template < typename T > -constexpr qua operator+(const qua& xs, const qua& ys); +constexpr auto operator+(const qua& xs, const qua& ys); // operator+= @@ -868,7 +868,7 @@ constexpr qua& operator+=(qua& xs, const qua& ys); // operator- template < typename T > -constexpr qua operator-(const qua& xs, const qua& ys); +constexpr auto operator-(const qua& xs, const qua& ys); // operator-= @@ -878,16 +878,16 @@ constexpr qua& operator-=(qua& xs, const qua& ys); // operator* template < typename T > -constexpr qua operator*(const qua& xs, T y); +constexpr auto operator*(const qua& xs, T y); template < typename T > -constexpr qua operator*(T x, const qua& ys); +constexpr auto operator*(T x, const qua& ys); template < typename T > -constexpr vec operator*(const vec& xs, const qua& ys); +constexpr auto operator*(const vec& xs, const qua& ys); template < typename T > -constexpr qua operator*(const qua& xs, const qua& ys); +constexpr auto operator*(const qua& xs, const qua& ys); // operator*= @@ -903,10 +903,10 @@ constexpr qua& operator*=(qua& xs, const qua& ys); // operator/ template < typename T > -constexpr qua operator/(const qua& xs, T y); +constexpr auto operator/(const qua& xs, T y); template < typename T > -constexpr qua operator/(T x, const qua& ys); +constexpr auto operator/(T x, const qua& ys); // operator/= diff --git a/headers/vmath.hpp/vmath_mat_fun.hpp b/headers/vmath.hpp/vmath_mat_fun.hpp index 3dc1eda..704f850 100644 --- a/headers/vmath.hpp/vmath_mat_fun.hpp +++ b/headers/vmath.hpp/vmath_mat_fun.hpp @@ -195,45 +195,45 @@ namespace vmath_hpp // +operator template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator+(const mat& xs) { + [[nodiscard]] constexpr auto operator+(const mat& xs) { return xs; } // -operator template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator-(const mat& xs) { + [[nodiscard]] constexpr auto operator-(const mat& xs) { return map_join([](const vec& x){ return -x; }, xs); } // ~operator template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator~(const mat& xs) { + [[nodiscard]] constexpr auto operator~(const mat& xs) { return map_join([](const vec& x){ return ~x; }, xs); } // !operator template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator!(const mat& xs) { + [[nodiscard]] constexpr auto operator!(const mat& xs) { return map_join([](const vec& x){ return !x; }, xs); } // operator+ template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator+(const mat& xs, T y) { + [[nodiscard]] constexpr auto operator+(const mat& xs, T y) { return map_join([y](const vec& x){ return x + y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator+(T x, const mat& ys) { + [[nodiscard]] constexpr auto operator+(T x, const mat& ys) { return map_join([x](const vec& y){ return x + y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator+(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr auto operator+(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return x + y; }, xs, ys); } @@ -252,17 +252,17 @@ namespace vmath_hpp // operator- template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator-(const mat& xs, T y) { + [[nodiscard]] constexpr auto operator-(const mat& xs, T y) { return map_join([y](const vec& x){ return x - y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator-(T x, const mat& ys) { + [[nodiscard]] constexpr auto operator-(T x, const mat& ys) { return map_join([x](const vec& y){ return x - y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator-(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr auto operator-(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return x - y; }, xs, ys); } @@ -281,24 +281,24 @@ namespace vmath_hpp // operator* template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator*(const mat& xs, T y) { + [[nodiscard]] constexpr auto operator*(const mat& xs, T y) { return map_join([y](const vec& x){ return x * y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator*(T x, const mat& ys) { + [[nodiscard]] constexpr auto operator*(T x, const mat& ys) { return map_join([x](const vec& y){ return x * y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator*(const vec& xs, const mat& ys) { + [[nodiscard]] constexpr auto operator*(const vec& xs, const mat& ys) { return fold_join([](const vec& acc, T x, const vec& y){ return acc + x * y; }, vec{}, xs, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator*(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr auto operator*(const mat& xs, const mat& ys) { return map_join([&ys](const vec& x){ return x * ys; }, xs); @@ -324,12 +324,12 @@ namespace vmath_hpp // operator/ template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator/(const mat& xs, T y) { + [[nodiscard]] constexpr auto operator/(const mat& xs, T y) { return map_join([y](const vec& x){ return x / y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator/(T x, const mat& ys) { + [[nodiscard]] constexpr auto operator/(T x, const mat& ys) { return map_join([x](const vec& y){ return x / y; }, ys); } @@ -343,17 +343,17 @@ namespace vmath_hpp // operator& template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator&(const mat& xs, T y) { + [[nodiscard]] constexpr auto operator&(const mat& xs, T y) { return map_join([y](const vec& x){ return x & y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator&(T x, const mat& ys) { + [[nodiscard]] constexpr auto operator&(T x, const mat& ys) { return map_join([x](const vec& y){ return x & y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator&(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr auto operator&(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return x & y; }, xs, ys); } @@ -372,17 +372,17 @@ namespace vmath_hpp // operator| template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator|(const mat& xs, T y) { + [[nodiscard]] constexpr auto operator|(const mat& xs, T y) { return map_join([y](const vec& x){ return x | y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator|(T x, const mat& ys) { + [[nodiscard]] constexpr auto operator|(T x, const mat& ys) { return map_join([x](const vec& y){ return x | y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator|(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr auto operator|(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return x | y; }, xs, ys); } @@ -401,17 +401,17 @@ namespace vmath_hpp // operator^ template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator^(const mat& xs, T y) { + [[nodiscard]] constexpr auto operator^(const mat& xs, T y) { return map_join([y](const vec& x){ return x ^ y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator^(T x, const mat& ys) { + [[nodiscard]] constexpr auto operator^(T x, const mat& ys) { return map_join([x](const vec& y){ return x ^ y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator^(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr auto operator^(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return x ^ y; }, xs, ys); } @@ -430,34 +430,34 @@ namespace vmath_hpp // operator&& template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator&&(const mat& xs, T y) { + [[nodiscard]] constexpr auto operator&&(const mat& xs, T y) { return map_join([y](const vec& x){ return x && y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator&&(T x, const mat& ys) { + [[nodiscard]] constexpr auto operator&&(T x, const mat& ys) { return map_join([x](const vec& y){ return x && y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator&&(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr auto operator&&(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return x && y; }, xs, ys); } // operator|| template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator||(const mat& xs, T y) { + [[nodiscard]] constexpr auto operator||(const mat& xs, T y) { return map_join([y](const vec& x){ return x || y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator||(T x, const mat& ys) { + [[nodiscard]] constexpr auto operator||(T x, const mat& ys) { return map_join([x](const vec& y){ return x || y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat operator||(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr auto operator||(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return x || y; }, xs, ys); } diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index 59d1624..3c5d574 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -23,21 +23,21 @@ namespace vmath_hpp // +operator template < typename T > - [[nodiscard]] constexpr qua operator+(const qua& xs) { + [[nodiscard]] constexpr auto operator+(const qua& xs) { return xs; } // -operator template < typename T > - [[nodiscard]] constexpr qua operator-(const qua& xs) { + [[nodiscard]] constexpr auto operator-(const qua& xs) { return qua(-vec{xs}); } // operator+ template < typename T > - [[nodiscard]] constexpr qua operator+(const qua& xs, const qua& ys) { + [[nodiscard]] constexpr auto operator+(const qua& xs, const qua& ys) { return qua(vec{xs} + vec{ys}); } @@ -51,7 +51,7 @@ namespace vmath_hpp // operator- template < typename T > - [[nodiscard]] constexpr qua operator-(const qua& xs, const qua& ys) { + [[nodiscard]] constexpr auto operator-(const qua& xs, const qua& ys) { return qua(vec{xs} - vec{ys}); } @@ -65,30 +65,30 @@ namespace vmath_hpp // operator* template < typename T > - [[nodiscard]] constexpr qua operator*(const qua& xs, T y) { + [[nodiscard]] constexpr auto operator*(const qua& xs, T y) { return qua(vec{xs} * y); } template < typename T > - [[nodiscard]] constexpr qua operator*(T x, const qua& ys) { + [[nodiscard]] constexpr auto operator*(T x, const qua& ys) { return qua(x * vec{ys}); } template < typename T > - [[nodiscard]] constexpr vec operator*(const vec& xs, const qua& ys) { + [[nodiscard]] constexpr auto operator*(const vec& xs, const qua& ys) { /// REFERENCE: /// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/transforms/ - const vec qv2 = cross(ys.v, xs) * T(2); + const vec qv2 = cross(ys.v, xs) * T{2}; return xs + qv2 * ys.s + cross(ys.v, qv2); } template < typename T > - [[nodiscard]] constexpr qua operator*(const qua& xs, const qua& ys) { + [[nodiscard]] constexpr auto operator*(const qua& xs, const qua& ys) { /// REFERENCE: /// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/arithmetic/ - return { + return qua{ cross(ys.v, xs.v) + ys.s * xs.v + xs.s * ys.v, ys.s * xs.s - dot(ys.v, xs.v)}; } @@ -113,12 +113,12 @@ namespace vmath_hpp // operator/ template < typename T > - [[nodiscard]] constexpr qua operator/(const qua& xs, T y) { + [[nodiscard]] constexpr auto operator/(const qua& xs, T y) { return qua(vec{xs} / y); } template < typename T > - [[nodiscard]] constexpr qua operator/(T x, const qua& ys) { + [[nodiscard]] constexpr auto operator/(T x, const qua& ys) { return qua(x / vec{ys}); } diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 979a3ec..017f940 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -199,45 +199,45 @@ namespace vmath_hpp // +operator template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator+(const vec& xs) { + [[nodiscard]] constexpr auto operator+(const vec& xs) { return xs; } // -operator template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator-(const vec& xs) { + [[nodiscard]] constexpr auto operator-(const vec& xs) { return map_join([](T x){ return -x; }, xs); } // ~operator template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator~(const vec& xs) { + [[nodiscard]] constexpr auto operator~(const vec& xs) { return map_join([](T x){ return ~x; }, xs); } // !operator template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator!(const vec& xs) { + [[nodiscard]] constexpr auto operator!(const vec& xs) { return map_join([](T x){ return !x; }, xs); } // operator+ template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator+(const vec& xs, T y) { + [[nodiscard]] constexpr auto operator+(const vec& xs, T y) { return map_join([y](T x){ return x + y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator+(T x, const vec& ys) { + [[nodiscard]] constexpr auto operator+(T x, const vec& ys) { return map_join([x](T y){ return x + y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator+(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr auto operator+(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return x + y; }, xs, ys); } @@ -256,17 +256,17 @@ namespace vmath_hpp // operator- template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator-(const vec& xs, T y) { + [[nodiscard]] constexpr auto operator-(const vec& xs, T y) { return map_join([y](T x){ return x - y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator-(T x, const vec& ys) { + [[nodiscard]] constexpr auto operator-(T x, const vec& ys) { return map_join([x](T y){ return x - y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator-(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr auto operator-(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return x - y; }, xs, ys); } @@ -285,17 +285,17 @@ namespace vmath_hpp // operator* template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator*(const vec& xs, T y) { + [[nodiscard]] constexpr auto operator*(const vec& xs, T y) { return map_join([y](T x){ return x * y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator*(T x, const vec& ys) { + [[nodiscard]] constexpr auto operator*(T x, const vec& ys) { return map_join([x](T y){ return x * y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator*(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr auto operator*(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return x * y; }, xs, ys); } @@ -314,17 +314,17 @@ namespace vmath_hpp // operator/ template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator/(const vec& xs, T y) { + [[nodiscard]] constexpr auto operator/(const vec& xs, T y) { return map_join([y](T x){ return x / y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator/(T x, const vec& ys) { + [[nodiscard]] constexpr auto operator/(T x, const vec& ys) { return map_join([x](T y){ return x / y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator/(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr auto operator/(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return x / y; }, xs, ys); } @@ -343,17 +343,17 @@ namespace vmath_hpp // operator& template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator&(const vec& xs, T y) { + [[nodiscard]] constexpr auto operator&(const vec& xs, T y) { return map_join([y](T x){ return x & y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator&(T x, const vec& ys) { + [[nodiscard]] constexpr auto operator&(T x, const vec& ys) { return map_join([x](T y){ return x & y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator&(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr auto operator&(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return x & y; }, xs, ys); } @@ -372,17 +372,17 @@ namespace vmath_hpp // operator| template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator|(const vec& xs, T y) { + [[nodiscard]] constexpr auto operator|(const vec& xs, T y) { return map_join([y](T x){ return x | y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator|(T x, const vec& ys) { + [[nodiscard]] constexpr auto operator|(T x, const vec& ys) { return map_join([x](T y){ return x | y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator|(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr auto operator|(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return x | y; }, xs, ys); } @@ -401,17 +401,17 @@ namespace vmath_hpp // operator^ template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator^(const vec& xs, T y) { + [[nodiscard]] constexpr auto operator^(const vec& xs, T y) { return map_join([y](T x){ return x ^ y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator^(T x, const vec& ys) { + [[nodiscard]] constexpr auto operator^(T x, const vec& ys) { return map_join([x](T y){ return x ^ y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator^(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr auto operator^(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return x ^ y; }, xs, ys); } @@ -430,34 +430,34 @@ namespace vmath_hpp // operator&& template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator&&(const vec& xs, T y) { + [[nodiscard]] constexpr auto operator&&(const vec& xs, T y) { return map_join([y](T x){ return x && y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator&&(T x, const vec& ys) { + [[nodiscard]] constexpr auto operator&&(T x, const vec& ys) { return map_join([x](T y){ return x && y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator&&(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr auto operator&&(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return x && y; }, xs, ys); } // operator|| template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator||(const vec& xs, T y) { + [[nodiscard]] constexpr auto operator||(const vec& xs, T y) { return map_join([y](T x){ return x || y; }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator||(T x, const vec& ys) { + [[nodiscard]] constexpr auto operator||(T x, const vec& ys) { return map_join([x](T y){ return x || y; }, ys); } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec operator||(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr auto operator||(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return x || y; }, xs, ys); } From bb6a04855d589c4bf1926a4d3d9a829ef27cb485 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 21 Feb 2021 01:39:57 +0700 Subject: [PATCH 06/15] relation funcs non-arithmetic T support --- README.md | 199 ++++++++++++++++++++-------- headers/vmath.hpp/vmath_mat_fun.hpp | 71 +++++++--- headers/vmath.hpp/vmath_qua_fun.hpp | 81 ++++++++--- headers/vmath.hpp/vmath_vec_fun.hpp | 73 ++++++---- untests/vmath_qua_fun_tests.cpp | 13 ++ 5 files changed, 314 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index 43cfac7..2b00337 100644 --- a/README.md +++ b/README.md @@ -1388,97 +1388,184 @@ constexpr bool not_equal_to(T x, T y) noexcept; #### Vector ```cpp -template < typename T, size_t Size > -constexpr bool any(const vec& xs); +template < typename T, std::size_t Size + , typename U = decltype(any(std::declval())) > +constexpr U any(const vec& xs); -template < typename T, size_t Size > -constexpr bool all(const vec& xs); +template < typename T, std::size_t Size + , typename U = decltype(all(std::declval())) > +constexpr U all(const vec& xs); -template < typename T, size_t Size > -constexpr vec approx(const vec& xs, const vec& ys); +template < typename T, std::size_t Size + , typename U = decltype(approx( + std::declval(), + std::declval())) > +constexpr vec approx(const vec& xs, const vec& ys); -template < typename T, size_t Size > -constexpr vec approx(const vec& xs, const vec& ys, T epsilon); +template < typename T, std::size_t Size + , typename U = decltype(approx( + std::declval(), + std::declval(), + std::declval())) > +constexpr vec approx(const vec& xs, const vec& ys, T epsilon); -template < typename T, size_t Size > -constexpr vec less(const vec& xs, const vec& ys); +template < typename T, std::size_t Size + , typename U = decltype(less( + std::declval(), + std::declval())) > +constexpr vec less(const vec& xs, const vec& ys); -template < typename T, size_t Size > -constexpr vec less_equal(const vec& xs, const vec& ys); +template < typename T, std::size_t Size + , typename U = decltype(less_equal( + std::declval(), + std::declval())) > +constexpr vec less_equal(const vec& xs, const vec& ys); -template < typename T, size_t Size > -constexpr vec greater(const vec& xs, const vec& ys); +template < typename T, std::size_t Size + , typename U = decltype(greater( + std::declval(), + std::declval())) > +constexpr vec greater(const vec& xs, const vec& ys); -template < typename T, size_t Size > -constexpr vec greater_equal(const vec& xs, const vec& ys); +template < typename T, std::size_t Size + , typename U = decltype(greater_equal( + std::declval(), + std::declval())) > +constexpr vec greater_equal(const vec& xs, const vec& ys); -template < typename T, size_t Size > -constexpr vec equal_to(const vec& xs, const vec& ys); +template < typename T, std::size_t Size + , typename U = decltype(equal_to( + std::declval(), + std::declval())) > +constexpr vec equal_to(const vec& xs, const vec& ys); -template < typename T, size_t Size > -constexpr vec not_equal_to(const vec& xs, const vec& ys); +template < typename T, std::size_t Size + , typename U = decltype(not_equal_to( + std::declval(), + std::declval())) > +constexpr vec not_equal_to(const vec& xs, const vec& ys); ``` #### Matrix ```cpp -template < typename T, size_t Size > -constexpr bool any(const mat& xs); +template < typename T, std::size_t Size + , typename U = decltype(any(std::declval>())) > +constexpr U any(const mat& xs); -template < typename T, size_t Size > -constexpr bool all(const mat& xs); +template < typename T, std::size_t Size + , typename U = decltype(all(std::declval>())) > +constexpr U all(const mat& xs); -template < typename T, size_t Size > -constexpr mat approx(const mat& xs, const mat& ys); +template < typename T, std::size_t Size + , typename U = typename decltype(approx( + std::declval>(), + std::declval>()))::component_type > +constexpr mat approx(const mat& xs, const mat& ys); -template < typename T, size_t Size > -constexpr mat approx(const mat& xs, const mat& ys, T epsilon); +template < typename T, std::size_t Size + , typename U = typename decltype(approx( + std::declval>(), + std::declval>(), + std::declval()))::component_type > +constexpr mat approx(const mat& xs, const mat& ys, T epsilon); -template < typename T, size_t Size > -constexpr mat less(const mat& xs, const mat& ys); +template < typename T, std::size_t Size + , typename U = typename decltype(less( + std::declval>(), + std::declval>()))::component_type > +constexpr mat less(const mat& xs, const mat& ys); -template < typename T, size_t Size > -constexpr mat less_equal(const mat& xs, const mat& ys); +template < typename T, std::size_t Size + , typename U = typename decltype(less_equal( + std::declval>(), + std::declval>()))::component_type > +constexpr mat less_equal(const mat& xs, const mat& ys); -template < typename T, size_t Size > -constexpr mat greater(const mat& xs, const mat& ys); +template < typename T, std::size_t Size + , typename U = typename decltype(greater( + std::declval>(), + std::declval>()))::component_type > +constexpr mat greater(const mat& xs, const mat& ys); -template < typename T, size_t Size > -constexpr mat greater_equal(const mat& xs, const mat& ys); +template < typename T, std::size_t Size + , typename U = typename decltype(greater_equal( + std::declval>(), + std::declval>()))::component_type > +constexpr mat greater_equal(const mat& xs, const mat& ys); -template < typename T, size_t Size > -constexpr mat equal_to(const mat& xs, const mat& ys); +template < typename T, std::size_t Size + , typename U = typename decltype(equal_to( + std::declval>(), + std::declval>()))::component_type > +constexpr mat equal_to(const mat& xs, const mat& ys); -template < typename T, size_t Size > -constexpr mat not_equal_to(const mat& xs, const mat& ys); +template < typename T, std::size_t Size + , typename U = typename decltype(not_equal_to( + std::declval>(), + std::declval>()))::component_type > +constexpr mat not_equal_to(const mat& xs, const mat& ys); ``` #### Quaternion ```cpp -template < typename T > -constexpr vec approx(const qua& xs, const qua& ys); +template < typename T + , typename U = decltype(any(std::declval>())) > +constexpr U any(const qua& xs); -template < typename T > -constexpr vec approx(const qua& xs, const qua& ys, T epsilon); +template < typename T + , typename U = decltype(all(std::declval>())) > +constexpr U all(const qua& xs); -template < typename T > -constexpr vec less(const qua& xs, const qua& ys); +template < typename T + , typename U = typename decltype(approx( + std::declval>(), + std::declval>()))::component_type > +constexpr vec approx(const qua& xs, const qua& ys); -template < typename T > -constexpr vec less_equal(const qua& xs, const qua& ys); +template < typename T + , typename U = typename decltype(approx( + std::declval>(), + std::declval>(), + std::declval()))::component_type > +constexpr vec approx(const qua& xs, const qua& ys, T epsilon); -template < typename T > -constexpr vec greater(const qua& xs, const qua& ys); +template < typename T + , typename U = typename decltype(less( + std::declval>(), + std::declval>()))::component_type > +constexpr vec less(const qua& xs, const qua& ys); -template < typename T > -constexpr vec greater_equal(const qua& xs, const qua& ys); +template < typename T + , typename U = typename decltype(less_equal( + std::declval>(), + std::declval>()))::component_type > +constexpr vec less_equal(const qua& xs, const qua& ys); -template < typename T > -constexpr vec equal_to(const qua& xs, const qua& ys); +template < typename T + , typename U = typename decltype(greater( + std::declval>(), + std::declval>()))::component_type > +constexpr vec greater(const qua& xs, const qua& ys); -template < typename T > -constexpr vec not_equal_to(const qua& xs, const qua& ys); +template < typename T + , typename U = typename decltype(greater_equal( + std::declval>(), + std::declval>()))::component_type > +constexpr vec greater_equal(const qua& xs, const qua& ys); + +template < typename T + , typename U = typename decltype(equal_to( + std::declval>(), + std::declval>()))::component_type > +constexpr vec equal_to(const qua& xs, const qua& ys); + +template < typename T + , typename U = typename decltype(not_equal_to( + std::declval>(), + std::declval>()))::component_type > +constexpr vec not_equal_to(const qua& xs, const qua& ys); ``` ### Matrix Functions diff --git a/headers/vmath.hpp/vmath_mat_fun.hpp b/headers/vmath.hpp/vmath_mat_fun.hpp index 704f850..2f0e053 100644 --- a/headers/vmath.hpp/vmath_mat_fun.hpp +++ b/headers/vmath.hpp/vmath_mat_fun.hpp @@ -501,53 +501,80 @@ namespace vmath_hpp namespace vmath_hpp { - template < typename T, std::size_t Size > - [[nodiscard]] constexpr bool any(const mat& xs) { - return fold_join([](bool acc, const vec& x){ return acc || any(x); }, false, xs); + template < typename T, std::size_t Size + , typename U = decltype(any(std::declval>())) > + [[nodiscard]] constexpr U any(const mat& xs) { + return fold_join([](U acc, const vec& x){ return acc || any(x); }, U{false}, xs); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr bool all(const mat& xs) { - return fold_join([](bool acc, const vec& x){ return acc && all(x); }, true, xs); + template < typename T, std::size_t Size + , typename U = decltype(all(std::declval>())) > + [[nodiscard]] constexpr U all(const mat& xs) { + return fold_join([](U acc, const vec& x){ return acc && all(x); }, U{true}, xs); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat approx(const mat& xs, const mat& ys) { + template < typename T, std::size_t Size + , typename U = typename decltype(approx( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr mat approx(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return approx(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat approx(const mat& xs, const mat& ys, T epsilon) { + template < typename T, std::size_t Size + , typename U = typename decltype(approx( + std::declval>(), + std::declval>(), + std::declval()))::component_type > + [[nodiscard]] constexpr mat approx(const mat& xs, const mat& ys, T epsilon) { return map_join([epsilon](const vec& x, const vec& y){ return approx(x, y, epsilon); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat less(const mat& xs, const mat& ys) { + template < typename T, std::size_t Size + , typename U = typename decltype(less( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr mat less(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return less(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat less_equal(const mat& xs, const mat& ys) { + template < typename T, std::size_t Size + , typename U = typename decltype(less_equal( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr mat less_equal(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return less_equal(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat greater(const mat& xs, const mat& ys) { + template < typename T, std::size_t Size + , typename U = typename decltype(greater( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr mat greater(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return greater(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat greater_equal(const mat& xs, const mat& ys) { + template < typename T, std::size_t Size + , typename U = typename decltype(greater_equal( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr mat greater_equal(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return greater_equal(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat equal_to(const mat& xs, const mat& ys) { + template < typename T, std::size_t Size + , typename U = typename decltype(equal_to( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr mat equal_to(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return equal_to(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr mat not_equal_to(const mat& xs, const mat& ys) { + template < typename T, std::size_t Size + , typename U = typename decltype(not_equal_to( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr mat not_equal_to(const mat& xs, const mat& ys) { return map_join([](const vec& x, const vec& y){ return not_equal_to(x, y); }, xs, ys); } } diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index 3c5d574..ea7b755 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -169,7 +169,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] qua nlerp(const qua& unit_xs, const qua& unit_ys, T a) { - const T xs_scale = T(1) - a; + const T xs_scale = T{1} - a; const T ys_scale = a * sign(dot(unit_xs, unit_ys)); return normalize(lerp(unit_xs, unit_ys, xs_scale, ys_scale)); } @@ -183,15 +183,15 @@ namespace vmath_hpp const T raw_cos_theta_sign = sign(raw_cos_theta); // half degree linear threshold: cos((pi / 180) * 0.25) - if ( const T cos_theta = raw_cos_theta * raw_cos_theta_sign; cos_theta < T(0.99999) ) { + if ( const T cos_theta = raw_cos_theta * raw_cos_theta_sign; cos_theta < T{0.99999} ) { const T theta = acos(cos_theta); - const T rsin_theta = rsqrt(T(1) - sqr(cos_theta)); - const T xs_scale = sin((T(1) - a) * theta) * rsin_theta; + const T rsin_theta = rsqrt(T{1} - sqr(cos_theta)); + const T xs_scale = sin((T{1} - a) * theta) * rsin_theta; const T ys_scale = sin(a * theta) * raw_cos_theta_sign * rsin_theta; return lerp(unit_xs, unit_ys, xs_scale, ys_scale); } else { // use linear interpolation for small angles - const T xs_scale = T(1) - a; + const T xs_scale = T{1} - a; const T ys_scale = a * raw_cos_theta_sign; return normalize(lerp(unit_xs, unit_ys, xs_scale, ys_scale)); } @@ -222,7 +222,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] T distance(const qua& xs, const qua& ys) { const qua zs = xs * conjugate(ys); - return T(2) * atan2(length(zs.v), abs(zs.s)); + return T{2} * atan2(length(zs.v), abs(zs.s)); } template < typename T > @@ -237,43 +237,80 @@ namespace vmath_hpp namespace vmath_hpp { - template < typename T > - [[nodiscard]] constexpr vec approx(const qua& xs, const qua& ys) { + template < typename T + , typename U = decltype(any(std::declval>())) > + [[nodiscard]] constexpr U any(const qua& xs) { + return any(vec{xs}); + } + + template < typename T + , typename U = decltype(all(std::declval>())) > + [[nodiscard]] constexpr U all(const qua& xs) { + return all(vec{xs}); + } + + template < typename T + , typename U = typename decltype(approx( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr vec approx(const qua& xs, const qua& ys) { return approx(vec{xs}, vec{ys}); } - template < typename T > - [[nodiscard]] constexpr vec approx(const qua& xs, const qua& ys, T epsilon) { + template < typename T + , typename U = typename decltype(approx( + std::declval>(), + std::declval>(), + std::declval()))::component_type > + [[nodiscard]] constexpr vec approx(const qua& xs, const qua& ys, T epsilon) { return approx(vec{xs}, vec{ys}, epsilon); } - template < typename T > - [[nodiscard]] constexpr vec less(const qua& xs, const qua& ys) { + template < typename T + , typename U = typename decltype(less( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr vec less(const qua& xs, const qua& ys) { return less(vec{xs}, vec{ys}); } - template < typename T > - [[nodiscard]] constexpr vec less_equal(const qua& xs, const qua& ys) { + template < typename T + , typename U = typename decltype(less_equal( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr vec less_equal(const qua& xs, const qua& ys) { return less_equal(vec{xs}, vec{ys}); } - template < typename T > - [[nodiscard]] constexpr vec greater(const qua& xs, const qua& ys) { + template < typename T + , typename U = typename decltype(greater( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr vec greater(const qua& xs, const qua& ys) { return greater(vec{xs}, vec{ys}); } - template < typename T > - [[nodiscard]] constexpr vec greater_equal(const qua& xs, const qua& ys) { + template < typename T + , typename U = typename decltype(greater_equal( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr vec greater_equal(const qua& xs, const qua& ys) { return greater_equal(vec{xs}, vec{ys}); } - template < typename T > - [[nodiscard]] constexpr vec equal_to(const qua& xs, const qua& ys) { + template < typename T + , typename U = typename decltype(equal_to( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr vec equal_to(const qua& xs, const qua& ys) { return equal_to(vec{xs}, vec{ys}); } - template < typename T > - [[nodiscard]] constexpr vec not_equal_to(const qua& xs, const qua& ys) { + template < typename T + , typename U = typename decltype(not_equal_to( + std::declval>(), + std::declval>()))::component_type > + [[nodiscard]] constexpr vec not_equal_to(const qua& xs, const qua& ys) { return not_equal_to(vec{xs}, vec{ys}); } } diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 017f940..44817a0 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -821,7 +821,7 @@ namespace vmath_hpp [[nodiscard]] constexpr T dot(const vec& xs, const vec& ys) { return fold_join([](T acc, T x, T y){ return acc + (x * y); - }, T(0), xs, ys); + }, T{0}, xs, ys); } template < typename T, std::size_t Size > @@ -869,53 +869,80 @@ namespace vmath_hpp namespace vmath_hpp { - template < typename T, std::size_t Size > - [[nodiscard]] constexpr bool any(const vec& xs) { - return fold_join([](bool acc, T x){ return acc || any(x); }, false, xs); + template < typename T, std::size_t Size + , typename U = decltype(any(std::declval())) > + [[nodiscard]] constexpr U any(const vec& xs) { + return fold_join([](U acc, T x){ return acc || any(x); }, U{false}, xs); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr bool all(const vec& xs) { - return fold_join([](bool acc, T x){ return acc && all(x); }, true, xs); + template < typename T, std::size_t Size + , typename U = decltype(all(std::declval())) > + [[nodiscard]] constexpr U all(const vec& xs) { + return fold_join([](U acc, T x){ return acc && all(x); }, U{true}, xs); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec approx(const vec& xs, const vec& ys) { + template < typename T, std::size_t Size + , typename U = decltype(approx( + std::declval(), + std::declval())) > + [[nodiscard]] constexpr vec approx(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return approx(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec approx(const vec& xs, const vec& ys, T epsilon) { + template < typename T, std::size_t Size + , typename U = decltype(approx( + std::declval(), + std::declval(), + std::declval())) > + [[nodiscard]] constexpr vec approx(const vec& xs, const vec& ys, T epsilon) { return map_join([epsilon](T x, T y){ return approx(x, y, epsilon); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec less(const vec& xs, const vec& ys) { + template < typename T, std::size_t Size + , typename U = decltype(less( + std::declval(), + std::declval())) > + [[nodiscard]] constexpr vec less(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return less(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec less_equal(const vec& xs, const vec& ys) { + template < typename T, std::size_t Size + , typename U = decltype(less_equal( + std::declval(), + std::declval())) > + [[nodiscard]] constexpr vec less_equal(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return less_equal(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec greater(const vec& xs, const vec& ys) { + template < typename T, std::size_t Size + , typename U = decltype(greater( + std::declval(), + std::declval())) > + [[nodiscard]] constexpr vec greater(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return greater(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec greater_equal(const vec& xs, const vec& ys) { + template < typename T, std::size_t Size + , typename U = decltype(greater_equal( + std::declval(), + std::declval())) > + [[nodiscard]] constexpr vec greater_equal(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return greater_equal(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec equal_to(const vec& xs, const vec& ys) { + template < typename T, std::size_t Size + , typename U = decltype(equal_to( + std::declval(), + std::declval())) > + [[nodiscard]] constexpr vec equal_to(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return equal_to(x, y); }, xs, ys); } - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec not_equal_to(const vec& xs, const vec& ys) { + template < typename T, std::size_t Size + , typename U = decltype(not_equal_to( + std::declval(), + std::declval())) > + [[nodiscard]] constexpr vec not_equal_to(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return not_equal_to(x, y); }, xs, ys); } } diff --git a/untests/vmath_qua_fun_tests.cpp b/untests/vmath_qua_fun_tests.cpp index 9b6df77..0c71cc3 100644 --- a/untests/vmath_qua_fun_tests.cpp +++ b/untests/vmath_qua_fun_tests.cpp @@ -150,6 +150,19 @@ TEST_CASE("vmath/qua_fun") { } SUBCASE("Relational Functions") { + STATIC_CHECK(any(qua(1,0,0,0))); + STATIC_CHECK(any(qua(0,1,0,0))); + STATIC_CHECK(any(qua(0,0,1,0))); + STATIC_CHECK(any(qua(0,0,0,1))); + STATIC_CHECK(any(qua(1,1,1,1))); + STATIC_CHECK_FALSE(any(qua(0,0,0,0))); + + STATIC_CHECK_FALSE(all(qua(1,0,0,0))); + STATIC_CHECK_FALSE(all(qua(0,1,0,0))); + STATIC_CHECK_FALSE(all(qua(0,0,1,0))); + STATIC_CHECK(all(qua(1,1,1,1))); + STATIC_CHECK_FALSE(all(qua(0,0,0,0))); + STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3)) == bool4(false, true, false, false)); STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 0) == bool4(false, true, false, false)); STATIC_CHECK(approx(qua(1,1,1,1), qua(0,1,2,3), 1) == bool4(true, true, true, false)); From aae8244575e365908206b7781a755780018eea97 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 21 Feb 2021 01:42:07 +0700 Subject: [PATCH 07/15] non-arithmetic T tests --- untests/vmath_fix_tests.cpp | 946 ++++++++++++++++++++++++++++++++++++ 1 file changed, 946 insertions(+) create mode 100644 untests/vmath_fix_tests.cpp diff --git a/untests/vmath_fix_tests.cpp b/untests/vmath_fix_tests.cpp new file mode 100644 index 0000000..d20ace1 --- /dev/null +++ b/untests/vmath_fix_tests.cpp @@ -0,0 +1,946 @@ +/******************************************************************************* + * This file is part of the "https://github.com/blackmatov/vmath.hpp" + * For conditions of distribution and use, see copyright notice in LICENSE.md + * Copyright (C) 2020-2021, by Matvey Cherevko (blackmatov@gmail.com) + ******************************************************************************/ + +#include "vmath_tests.hpp" + +namespace +{ + using namespace vmath_hpp; + using namespace vmath_tests; + + template < typename T > + class fix { + public: + fix() = default; + + fix(fix&&) = default; + fix& operator=(fix&&) = default; + + fix(const fix&) = default; + fix& operator=(const fix&) = default; + + constexpr explicit fix(T underlying): underlying_(underlying) {} + constexpr T underlying() const noexcept { return underlying_; } + + constexpr friend fix abs(const fix& l) { return { fix{abs(l.underlying())} }; } + constexpr friend fix sqr(const fix& l) { return { fix{sqr(l.underlying())} }; } + constexpr friend fix sign(const fix& l) { return { fix{sign(l.underlying())} }; } + + constexpr friend fix rcp(const fix& l) { return { fix{rcp(l.underlying())} }; } + constexpr friend fix floor(const fix& l) { return { fix{floor(l.underlying())} }; } + constexpr friend fix trunc(const fix& l) { return { fix{trunc(l.underlying())} }; } + constexpr friend fix round(const fix& l) { return { fix{round(l.underlying())} }; } + constexpr friend fix ceil(const fix& l) { return { fix{ceil(l.underlying())} }; } + constexpr friend fix fract(const fix& l) { return { fix{fract(l.underlying())} }; } + + constexpr friend fix fmod(const fix& l, const fix& r) { return { fix{fmod(l.underlying(), r.underlying())} }; } + constexpr friend fix copysign(const fix& l, const fix& r) { return { fix{copysign(l.underlying(), r.underlying())} }; } + + constexpr friend fix min(const fix& l, const fix& r) { return fix{min(l.underlying(), r.underlying())}; } + constexpr friend fix max(const fix& l, const fix& r) { return fix{max(l.underlying(), r.underlying())}; } + constexpr friend fix clamp(const fix& l, const fix& min_l, const fix& max_l) { return fix{clamp(l.underlying(), min_l.underlying(), max_l.underlying())}; } + constexpr friend fix saturate(const fix& l) { return fix{saturate(l.underlying())}; } + constexpr friend fix lerp(const fix& l, const fix& r, const fix& a) { return fix{lerp(l.underlying(), r.underlying(), a.underlying())}; } + constexpr friend fix lerp(const fix& l, const fix& r, const fix& a, const fix& b) { return fix{lerp(l.underlying(), r.underlying(), a.underlying(), b.underlying())}; } + + constexpr friend fix step(const fix& e, const fix& l) { return fix{step(e.underlying(), l.underlying())}; } + constexpr friend fix smoothstep(const fix& e0, const fix& e1, const fix& l) { return fix{smoothstep(e0.underlying(), e1.underlying(), l.underlying())}; } + + constexpr friend fix fma(const fix& x, const fix& y, const fix& z) { return fix{fma(x.underlying(), y.underlying(), z.underlying())}; } + + // + + constexpr friend fix any(const fix& l) { return fix{any(l.underlying())}; } + constexpr friend fix all(const fix& l) { return fix{all(l.underlying())}; } + + constexpr friend fix approx(const fix& l, const fix& r) { return fix{approx(l.underlying(), r.underlying())}; } + constexpr friend fix approx(const fix& l, const fix& r, const fix& e) { return fix{approx(l.underlying(), r.underlying(), e.underlying())}; } + + constexpr friend fix less(const fix& l, const fix& r) { return fix{less(l.underlying(), r.underlying())}; } + constexpr friend fix less_equal(const fix& l, const fix& r) { return fix{less_equal(l.underlying(), r.underlying())}; } + constexpr friend fix greater(const fix& l, const fix& r) { return fix{greater(l.underlying(), r.underlying())}; } + constexpr friend fix greater_equal(const fix& l, const fix& r) { return fix{greater_equal(l.underlying(), r.underlying())}; } + constexpr friend fix equal_to(const fix& l, const fix& r) { return fix{equal_to(l.underlying(), r.underlying())}; } + constexpr friend fix not_equal_to(const fix& l, const fix& r) { return fix{not_equal_to(l.underlying(), r.underlying())}; } + + // + + constexpr friend fix radians(const fix& l) { return fix{radians(l.underlying())}; } + constexpr friend fix degrees(const fix& l) { return fix{degrees(l.underlying())}; } + friend fix sin(const fix& l) { return fix{sin(l.underlying())}; } + friend fix cos(const fix& l) { return fix{cos(l.underlying())}; } + friend fix tan(const fix& l) { return fix{tan(l.underlying())}; } + friend fix asin(const fix& l) { return fix{asin(l.underlying())}; } + friend fix acos(const fix& l) { return fix{acos(l.underlying())}; } + friend fix atan(const fix& l) { return fix{atan(l.underlying())}; } + friend fix atan2(const fix& l, const fix& r) { return fix{atan2(l.underlying(), r.underlying())}; } + friend fix sinh(const fix& l) { return fix{sinh(l.underlying())}; } + friend fix cosh(const fix& l) { return fix{cosh(l.underlying())}; } + friend fix tanh(const fix& l) { return fix{tanh(l.underlying())}; } + friend fix asinh(const fix& l) { return fix{asinh(l.underlying())}; } + friend fix acosh(const fix& l) { return fix{acosh(l.underlying())}; } + friend fix atanh(const fix& l) { return fix{atanh(l.underlying())}; } + friend std::pair sincos(const fix& l) { return { sin(l), cos(l) }; } + friend void sincos(const fix& l, fix* s, fix* c) { *s = sin(l); *c = cos(l); } + + // + + friend fix pow(const fix& l, const fix& r) { return fix{pow(l.underlying(), r.underlying())}; } + friend fix exp(const fix& l) { return fix{exp(l.underlying())}; } + friend fix log(const fix& l) { return fix{log(l.underlying())}; } + friend fix exp2(const fix& l) { return fix{exp2(l.underlying())}; } + friend fix log2(const fix& l) { return fix{log2(l.underlying())}; } + friend fix sqrt(const fix& l) { return fix{sqrt(l.underlying())}; } + friend fix rsqrt(const fix& l) { return fix{rsqrt(l.underlying())}; } + + // + + constexpr friend fix operator+(const fix& l) { return { fix{+l.underlying()} }; } + constexpr friend fix operator-(const fix& l) { return { fix{-l.underlying()} }; } + constexpr friend fix operator~(const fix& l) { return { fix{~l.underlying()} }; } + constexpr friend fix operator!(const fix& l) { return { fix{!l.underlying()} }; } + + constexpr friend fix operator+(const fix& l, const fix& r) { return fix{l.underlying() + r.underlying()}; } + constexpr friend fix operator-(const fix& l, const fix& r) { return fix{l.underlying() - r.underlying()}; } + constexpr friend fix operator*(const fix& l, const fix& r) { return fix{l.underlying() * r.underlying()}; } + constexpr friend fix operator/(const fix& l, const fix& r) { return fix{l.underlying() / r.underlying()}; } + + constexpr friend fix operator&(const fix& l, const fix& r) { return fix{l.underlying() & r.underlying()}; } + constexpr friend fix operator|(const fix& l, const fix& r) { return fix{l.underlying() | r.underlying()}; } + constexpr friend fix operator^(const fix& l, const fix& r) { return fix{l.underlying() ^ r.underlying()}; } + + constexpr friend fix operator&&(const fix& l, const fix& r) { return fix{l.underlying() && r.underlying()}; } + constexpr friend fix operator||(const fix& l, const fix& r) { return fix{l.underlying() || r.underlying()}; } + + constexpr friend bool operator<(const fix& l, const fix& r) { return l.underlying() < r.underlying(); } + constexpr friend bool operator==(const fix& l, const fix& r) { return l.underlying() == r.underlying(); } + constexpr friend bool operator!=(const fix& l, const fix& r) { return l.underlying() != r.underlying(); } + private: + T underlying_{}; + }; + + using qfix = qua>; + + using fix2b = vec, 2>; + using fix3b = vec, 3>; + using fix4b = vec, 4>; + + using fix2i = vec, 2>; + using fix3i = vec, 3>; + using fix4i = vec, 4>; + + using fix2f = vec, 2>; + using fix3f = vec, 3>; + using fix4f = vec, 4>; + + using fix2x2b = mat, 2>; + using fix3x3b = mat, 3>; + using fix4x4b = mat, 4>; + + using fix2x2i = mat, 2>; + using fix3x3i = mat, 3>; + using fix4x4i = mat, 4>; + + using fix2x2f = mat, 2>; + using fix3x3f = mat, 3>; + using fix4x4f = mat, 4>; +} + +// +// Common Functions +// + +namespace vmath_hpp +{ + template fix2f abs(const fix2f&); + template fix2f sqr(const fix2f&); + template fix2f sign(const fix2f&); + + template fix2f rcp(const fix2f&); + template fix2f floor(const fix2f&); + template fix2f trunc(const fix2f&); + template fix2f round(const fix2f&); + template fix2f ceil(const fix2f&); + template fix2f fract(const fix2f&); + + template fix2f fmod(const fix2f&, fix); + template fix2f fmod(const fix2f&, const fix2f&); + + template fix2f copysign(const fix2f&, fix); + template fix2f copysign(const fix2f&, const fix2f&); + + template fix min(const fix2f&); + template fix2f min(const fix2f&, fix); + template fix2f min(fix, const fix2f&); + template fix2f min(const fix2f&, const fix2f&); + + template fix max(const fix2f&); + template fix2f max(const fix2f&, fix); + template fix2f max(fix, const fix2f&); + template fix2f max(const fix2f&, const fix2f&); + + template fix2f clamp(const fix2f&, fix, fix); + template fix2f clamp(const fix2f&, const fix2f&, const fix2f&); + + template fix2f saturate(const fix2f&); + + template fix2f lerp(const fix2f&, const fix2f&, fix); + template fix2f lerp(const fix2f&, const fix2f&, fix, fix); + template fix2f lerp(const fix2f&, const fix2f&, const fix2f&); + template fix2f lerp(const fix2f&, const fix2f&, const fix2f&, const fix2f&); + + template fix2f step(fix, const fix2f&); + template fix2f step(const fix2f&, const fix2f&); + template fix2f smoothstep(fix, fix, const fix2f&); + template fix2f smoothstep(const fix2f&, const fix2f&, const fix2f&); + + template fix2f fma(const fix2f&, const fix2f&, const fix2f&); +} + +namespace vmath_hpp +{ + template qfix lerp(const qfix&, const qfix&, fix); + template qfix lerp(const qfix&, const qfix&, fix, fix); + template qfix nlerp(const qfix&, const qfix&, fix); + template qfix slerp(const qfix&, const qfix&, fix); +} + +// +// Angle and Trigonometric Functions +// + +namespace vmath_hpp +{ + template fix2f radians(const fix2f&); + template fix2f degrees(const fix2f&); + template fix2f sin(const fix2f&); + template fix2f cos(const fix2f&); + template fix2f tan(const fix2f&); + template fix2f asin(const fix2f&); + template fix2f acos(const fix2f&); + template fix2f atan(const fix2f&); + template fix2f atan2(const fix2f&, const fix2f&); + template fix2f sinh(const fix2f&); + template fix2f cosh(const fix2f&); + template fix2f tanh(const fix2f&); + template fix2f asinh(const fix2f&); + template fix2f acosh(const fix2f&); + template fix2f atanh(const fix2f&); + template std::pair sincos(const fix2f&); + template void sincos(const fix2f&, fix2f*, fix2f*); +} + +// +// Exponential Functions +// + +namespace vmath_hpp +{ + template fix2f pow(const fix2f&, const fix2f&); + template fix2f exp(const fix2f&); + template fix2f log(const fix2f&); + template fix2f exp2(const fix2f&); + template fix2f log2(const fix2f&); + template fix2f sqrt(const fix2f&); + template fix2f rsqrt(const fix2f&); +} + +// +// Geometric Functions +// + +namespace vmath_hpp +{ + template fix dot(const fix2f&, const fix2f&); + template fix length(const fix2f&); + template fix length2(const fix2f&); + template fix distance(const fix2f&, const fix2f&); + template fix distance2(const fix2f&, const fix2f&); + template fix cross(const fix2f&, const fix2f&); + template fix3f cross(const fix3f&, const fix3f&); + template fix2f normalize(const fix2f&); +} + +namespace vmath_hpp +{ + template fix dot(const qfix&, const qfix&); + template fix length(const qfix&); + template fix length2(const qfix&); + template fix distance(const qfix&, const qfix&); + template qfix normalize(const qfix&); +} + +// +// Relational Functions +// + +namespace vmath_hpp +{ + template fix any(const fix2f&); + template fix all(const fix2f&); + template fix2b approx(const fix2f&, const fix2f&); + template fix2b approx(const fix2f&, const fix2f&, fix); + template fix2b less(const fix2f&, const fix2f&); + template fix2b less_equal(const fix2f&, const fix2f&); + template fix2b greater(const fix2f&, const fix2f&); + template fix2b greater_equal(const fix2f&, const fix2f&); + template fix2b equal_to(const fix2f&, const fix2f&); + template fix2b not_equal_to(const fix2f&, const fix2f&); +} + +namespace vmath_hpp +{ + template fix any(const fix2x2f&); + template fix all(const fix2x2f&); + template fix2x2b approx(const fix2x2f&, const fix2x2f&); + template fix2x2b approx(const fix2x2f&, const fix2x2f&, fix); + template fix2x2b less(const fix2x2f&, const fix2x2f&); + template fix2x2b less_equal(const fix2x2f&, const fix2x2f&); + template fix2x2b greater(const fix2x2f&, const fix2x2f&); + template fix2x2b greater_equal(const fix2x2f&, const fix2x2f&); + template fix2x2b equal_to(const fix2x2f&, const fix2x2f&); + template fix2x2b not_equal_to(const fix2x2f&, const fix2x2f&); +} + +namespace vmath_hpp +{ + template fix any(const qfix&); + template fix all(const qfix&); + template fix4b approx(const qfix&, const qfix&); + template fix4b approx(const qfix&, const qfix&, fix); + template fix4b less(const qfix&, const qfix&); + template fix4b less_equal(const qfix&, const qfix&); + template fix4b greater(const qfix&, const qfix&); + template fix4b greater_equal(const qfix&, const qfix&); + template fix4b equal_to(const qfix&, const qfix&); + template fix4b not_equal_to(const qfix&, const qfix&); +} + +// +// Matrix Functions +// + +namespace vmath_hpp +{ + template fix2x2f transpose(const fix2x2f&); + template fix3x3f transpose(const fix3x3f&); + template fix4x4f transpose(const fix4x4f&); + + template fix determinant(const fix2x2f&); + template fix determinant(const fix3x3f&); + template fix determinant(const fix4x4f&); + + template fix2x2f inverse(const fix2x2f&); + template fix3x3f inverse(const fix3x3f&); + template fix4x4f inverse(const fix4x4f&); +} + +// +// Quaternion Functions +// + +namespace vmath_hpp +{ + template qfix conjugate(const qfix&); + template qfix inverse(const qfix&); +} + +// +// Access +// + +namespace vmath_hpp +{ + template fix component(const fix2f&, std::size_t); + template fix2f component(fix2f, std::size_t, fix); + + template fix2f row(const fix2x2f&, std::size_t); + template fix2x2f row(fix2x2f, std::size_t, const fix2f&); + + template fix2f column(const fix2x2f&, std::size_t); + template fix2x2f column(const fix2x2f&, std::size_t, const fix2f&); + + template fix real(const qfix&); + template qfix real(qfix, fix); + + template fix3f imag(const qfix&); + template qfix imag(qfix, const fix3f&); +} + +// +// Matrix Transform 3D +// + +namespace vmath_hpp +{ + template fix4x4f translate(fix x, fix y, fix z); + template fix4x4f translate(const fix4x4f&, fix, fix, fix); + template fix4x4f translate(const fix3f&); + template fix4x4f translate(const fix4x4f&, const fix3f&); + + template fix4x4f rotate(const qfix&); + template fix4x4f rotate(const fix4x4f&, const qfix&); + template fix4x4f rotate(fix, const fix3f&); + template fix4x4f rotate(const fix4x4f&, fix, const fix3f&); + + template fix4x4f rotate_x(fix); + template fix4x4f rotate_x(const fix4x4f&, fix); + + template fix4x4f rotate_y(fix); + template fix4x4f rotate_y(const fix4x4f&, fix); + + template fix4x4f rotate_z(fix); + template fix4x4f rotate_z(const fix4x4f&, fix); + + template fix4x4f scale(fix, fix, fix); + template fix4x4f scale(const fix4x4f&, fix, fix, fix); + template fix4x4f scale(const fix3f&); + template fix4x4f scale(const fix4x4f&, const fix3f&); + + template fix4x4f look_at_lh(const fix3f&, const fix3f&, const fix3f&); + template fix4x4f look_at_rh(const fix3f&, const fix3f&, const fix3f&); +} + +// +// Matrix Transform 2D +// + +namespace vmath_hpp +{ + template fix3x3f translate(fix, fix); + template fix3x3f translate(const fix3x3f&, fix, fix); + template fix3x3f translate(const fix2f&); + template fix3x3f translate(const fix3x3f&, const fix2f&); + + template fix3x3f rotate(fix); + template fix3x3f rotate(const fix3x3f&, fix); + + template fix3x3f scale(fix, fix); + template fix3x3f scale(const fix3x3f&, fix, fix); + template fix3x3f scale(const fix2f&); + template fix3x3f scale(const fix3x3f&, const fix2f&); + + template fix3x3f shear(fix, fix); + template fix3x3f shear(const fix3x3f&, fix, fix); + template fix3x3f shear(const fix2f&); + template fix3x3f shear(const fix3x3f&, const fix2f&); + + template fix3x3f shear_x(fix); + template fix3x3f shear_x(const fix3x3f&, fix); + + template fix3x3f shear_y(fix); + template fix3x3f shear_y(const fix3x3f&, fix); +} + +// +// Matrix Projections +// + +namespace vmath_hpp +{ + template fix4x4f orthographic_lh(fix, fix, fix, fix); + template fix4x4f orthographic_rh(fix, fix, fix, fix); + + template fix4x4f orthographic_lh(fix, fix, fix, fix, fix, fix); + template fix4x4f orthographic_rh(fix, fix, fix, fix, fix, fix); + + template fix4x4f perspective_lh(fix, fix, fix, fix); + template fix4x4f perspective_rh(fix, fix, fix, fix); + + template fix4x4f perspective_lh(fix, fix, fix, fix, fix, fix); + template fix4x4f perspective_rh(fix, fix, fix, fix, fix, fix); + + template fix4x4f perspective_fov_lh(fix, fix, fix, fix); + template fix4x4f perspective_fov_rh(fix, fix, fix, fix); +} + +// +// Vector Transform +// + +namespace vmath_hpp +{ + template fix angle(const fix3f&, const fix3f&); + template fix2f rotate(const fix2f&, fix); + template fix3f rotate_x(const fix3f&, fix); + template fix3f rotate_y(const fix3f&, fix); + template fix3f rotate_z(const fix3f&, fix); + template fix3f rotate(const fix3f&, const qfix&); + template fix3f rotate(const fix3f&, fix, const fix3f&); + template fix3f project(const fix3f&, const fix3f&); + template fix3f perpendicular(const fix3f&, const fix3f&); +} + +// +// Quaternion Transform +// + +namespace vmath_hpp +{ + template qfix qrotate(const fix3x3f&); + template qfix qrotate(const qfix&, const fix3x3f&); + + template qfix qrotate(const fix3f&, const fix3f&); + template qfix qrotate(const qfix&, const fix3f&, const fix3f&); + + template qfix qrotate(fix, const fix3f&); + template qfix qrotate(const qfix&, fix, const fix3f&); + + template qfix qrotate_x(fix); + template qfix qrotate_x(const qfix&, fix); + + template qfix qrotate_y(fix); + template qfix qrotate_y(const qfix&, fix); + + template qfix qrotate_z(fix); + template qfix qrotate_z(const qfix&, fix); + + template qfix qlook_at_lh(const fix3f&, const fix3f&); + template qfix qlook_at_rh(const fix3f&, const fix3f&); +} + +// +// fix_vec +// + +TEST_CASE("vmath/fix_vec") { + SUBCASE("fix2 ctors") { + constexpr fix2i v0{}; + constexpr fix2i v1{fix(1)}; + constexpr fix2i v2{fix(1), fix(2)}; + constexpr fix2i v3{fix3i{fix(1), fix(2), fix(3)}}; + constexpr fix2i v4{fix4i{fix(1), fix(2), fix(3), fix(4)}}; + + STATIC_CHECK((v0[0] == fix(0))); + STATIC_CHECK((v1[0] == fix(1) && v1[1] == fix(1))); + STATIC_CHECK((v2[0] == fix(1) && v2[1] == fix(2))); + STATIC_CHECK((v3[0] == fix(1) && v3[1] == fix(2))); + STATIC_CHECK((v4[0] == fix(1) && v4[1] == fix(2))); + } + + SUBCASE("fix3 ctors") { + constexpr fix3i v0{}; + constexpr fix3i v1{fix(1)}; + constexpr fix3i v2{fix(1), fix(2), fix(3)}; + constexpr fix3i v3{fix2i{fix(1), fix(2)}, fix(3)}; + constexpr fix3i v4{fix(1), fix2i{fix(2), fix(3)}}; + constexpr fix3i v5{fix4i{fix(1), fix(2), fix(3), fix(4)}}; + + STATIC_CHECK((v0[0] == fix(0))); + STATIC_CHECK((v1[0] == fix(1) && v1[1] == fix(1) && v1[2] == fix(1))); + STATIC_CHECK((v2[0] == fix(1) && v2[1] == fix(2) && v2[2] == fix(3))); + STATIC_CHECK((v3[0] == fix(1) && v3[1] == fix(2) && v3[2] == fix(3))); + STATIC_CHECK((v4[0] == fix(1) && v4[1] == fix(2) && v4[2] == fix(3))); + STATIC_CHECK((v5[0] == fix(1) && v5[1] == fix(2) && v5[2] == fix(3))); + } + + SUBCASE("fix4 ctors") { + constexpr fix4i v0{}; + constexpr fix4i v1{fix(1)}; + constexpr fix4i v2{fix(1), fix(2), fix(3), fix(4)}; + constexpr fix4i v3{fix2i{fix(1), fix(2)}, fix(3), fix(4)}; + constexpr fix4i v4{fix(1), fix2i{fix(2), fix(3)}, fix(4)}; + constexpr fix4i v5{fix(1), fix(2), fix2i{fix(3), fix(4)}}; + constexpr fix4i v6{fix2i{fix(1), fix(2)}, fix2i{fix(3), fix(4)}}; + constexpr fix4i v7{fix3i{fix(1), fix(2), fix(3)}, fix(4)}; + constexpr fix4i v8{fix(1), fix3i{fix(2), fix(3), fix(4)}}; + + STATIC_CHECK((v0.at(0) == fix(0))); + STATIC_CHECK((v1.at(0) == fix(1) && v1.at(1) == fix(1) && v1.at(2) == fix(1) && v1.at(3) == fix(1))); + STATIC_CHECK((v2.at(0) == fix(1) && v2.at(1) == fix(2) && v2.at(2) == fix(3) && v2.at(3) == fix(4))); + STATIC_CHECK((v3.at(0) == fix(1) && v3.at(1) == fix(2) && v3.at(2) == fix(3) && v3.at(3) == fix(4))); + STATIC_CHECK((v4.at(0) == fix(1) && v4.at(1) == fix(2) && v4.at(2) == fix(3) && v4.at(3) == fix(4))); + STATIC_CHECK((v5.at(0) == fix(1) && v5.at(1) == fix(2) && v5.at(2) == fix(3) && v5.at(3) == fix(4))); + STATIC_CHECK((v6.at(0) == fix(1) && v6.at(1) == fix(2) && v6.at(2) == fix(3) && v6.at(3) == fix(4))); + STATIC_CHECK((v7.at(0) == fix(1) && v7.at(1) == fix(2) && v7.at(2) == fix(3) && v7.at(3) == fix(4))); + STATIC_CHECK((v8.at(0) == fix(1) && v8.at(1) == fix(2) && v8.at(2) == fix(3) && v8.at(3) == fix(4))); + } + + SUBCASE("swap") { + { + vec v0{fix(1), fix(2)}; + vec v1{fix(3), fix(4)}; + swap(v0, v1); + CHECK(v0 == fix2i(fix(3),fix(4))); + CHECK(v1 == fix2i(fix(1),fix(2))); + } + { + vec v0{fix{1},fix{2},fix{3}}; + vec v1{fix2i{fix(3),fix(4)}, fix{5}}; + swap(v0, v1); + CHECK(v0 == fix3i(fix(3),fix(4),fix(5))); + CHECK(v1 == fix3i(fix(1),fix(2),fix(3))); + } + { + vec v0{fix{1},fix{2},fix{3},fix{4}}; + vec v1{fix{3},fix3i{fix(4),fix(5),fix(6)}}; + swap(v0, v1); + CHECK(v0 == fix4i(fix(3),fix(4),fix(5),fix(6))); + CHECK(v1 == fix4i(fix(1),fix(2),fix(3),fix(4))); + } + } + + SUBCASE("operators") { + fix2b vb{}; + fix2i vi{}; + bool b{}; + + vi = {+fix2i{fix(1),fix(2)}}; + vi = {-fix2i{fix(1),fix(2)}}; + vi = {~fix2i{fix(1),fix(2)}}; + vb = {!fix2i{fix(1),fix(2)}}; + + vi = {fix2i{fix(1),fix(2)} + fix{3}}; + vi = {fix{3} + fix2i{fix(1),fix(2)}}; + vi = {fix2i{fix(1),fix(2)} + fix2i{fix(1),fix(2)}}; + + vi = {fix2i{fix(1),fix(2)} - fix{3}}; + vi = {fix{3} - fix2i{fix(1),fix(2)}}; + vi = {fix2i{fix(1),fix(2)} - fix2i{fix(1),fix(2)}}; + + vi = {fix2i{fix(1),fix(2)} * fix{3}}; + vi = {fix{3} * fix2i{fix(1),fix(2)}}; + vi = {fix2i{fix(1),fix(2)} * fix2i{fix(1),fix(2)}}; + + vi = {fix2i{fix(1),fix(2)} / fix{3}}; + vi = {fix{3} / fix2i{fix(1),fix(2)}}; + vi = {fix2i{fix(1),fix(2)} / fix2i{fix(1),fix(2)}}; + + vi = {fix2i{fix(1),fix(2)} & fix{3}}; + vi = {fix{3} & fix2i{fix(1),fix(2)}}; + vi = {fix2i{fix(1),fix(2)} & fix2i{fix(1),fix(2)}}; + + vi = {fix2i{fix(1),fix(2)} | fix{3}}; + vi = {fix{3} | fix2i{fix(1),fix(2)}}; + vi = {fix2i{fix(1),fix(2)} | fix2i{fix(1),fix(2)}}; + + vi = {fix2i{fix(1),fix(2)} ^ fix{3}}; + vi = {fix{3} ^ fix2i{fix(1),fix(2)}}; + vi = {fix2i{fix(1),fix(2)} ^ fix2i{fix(1),fix(2)}}; + + vb = {fix2i{fix(1),fix(2)} && fix{3}}; + vb = {fix{3} && fix2i{fix(1),fix(2)}}; + vb = {fix2i{fix(1),fix(2)} && fix2i{fix(1),fix(2)}}; + + vb = {fix2i{fix(1),fix(2)} || fix{3}}; + vb = {fix{3} || fix2i{fix(1),fix(2)}}; + vb = {fix2i{fix(1),fix(2)} || fix2i{fix(1),fix(2)}}; + + b = {fix2i{fix(1),fix(2)} == fix2i{fix(3),fix(4)}}; + b = {fix2i{fix(1),fix(2)} != fix2i{fix(3),fix(4)}}; + b = {fix2i{fix(1),fix(2)} < fix2i{fix(3),fix(4)}}; + + { + fix2i v{}; + fix2i vi{}; + vi = {v += fix{3}}; + vi = {v += fix2i{fix(4),fix(5)}}; + vi = {v -= fix{3}}; + vi = {v -= fix2i{fix(4),fix(5)}}; + vi = {v *= fix{3}}; + vi = {v *= fix2i{fix(4),fix(5)}}; + vi = {v /= fix{3}}; + vi = {v /= fix2i{fix(4),fix(5)}}; + vi = {v &= fix{3}}; + vi = {v &= fix2i{fix(4),fix(5)}}; + vi = {v |= fix{3}}; + vi = {v |= fix2i{fix(4),fix(5)}}; + vi = {v ^= fix{3}}; + vi = {v ^= fix2i{fix(4),fix(5)}}; + } + } +} + +// +// fix_mat +// + +TEST_CASE("vmath/fix_mat") { + SUBCASE("fix2x2 ctors") { + constexpr fix2x2i v0{}; + constexpr fix2x2i v1{fix(2)}; + constexpr fix2x2i v2{fix2i{fix(1), fix(2)}}; + constexpr fix2x2i v3{fix(1), fix(2), fix(3), fix(4)}; + constexpr fix2x2i v4{{fix(1), fix(2)}, {fix(3), fix(4)}}; + constexpr fix2x2i v5{fix3x3i{fix(1)}}; + constexpr fix2x2i v6{fix4x4i{fix(1)}}; + + STATIC_CHECK((v0[0] == fix2i(fix(1),fix(0)) && v0[1] == fix2i(fix(0),fix(1)))); + STATIC_CHECK((v1[0] == fix2i(fix(2),fix(0)) && v1[1] == fix2i(fix(0),fix(2)))); + STATIC_CHECK((v2[0] == fix2i(fix(1),fix(0)) && v2[1] == fix2i(fix(0),fix(2)))); + STATIC_CHECK((v3[0] == fix2i(fix(1),fix(2)) && v3[1] == fix2i(fix(3),fix(4)))); + STATIC_CHECK((v4[0] == fix2i(fix(1),fix(2)) && v4[1] == fix2i(fix(3),fix(4)))); + STATIC_CHECK((v5[0] == fix2i(fix(1),fix(0)) && v5[1] == fix2i(fix(0),fix(1)))); + STATIC_CHECK((v6[0] == fix2i(fix(1),fix(0)) && v6[1] == fix2i(fix(0),fix(1)))); + } + + SUBCASE("fix3x3 ctors") { + constexpr fix3x3i v0{}; + constexpr fix3x3i v1{fix(2)}; + constexpr fix3x3i v2{fix3i{fix(1), fix(2), fix(3)}}; + constexpr fix3x3i v3{fix(1),fix(2),fix(3),fix(4),fix(5),fix(6),fix(7),fix(8),fix(9)}; + constexpr fix3x3i v4{{fix(1),fix(2),fix(3)},{fix(4),fix(5),fix(6)},{fix(7),fix(8),fix(9)}}; + constexpr fix3x3i v5{fix2x2i{fix(1)},fix2i{fix(0)}}; + constexpr fix3x3i v6{fix2x2i{fix(1)}}; + constexpr fix3x3i v7{fix4x4i{fix(1)}}; + + STATIC_CHECK((v0[0] == fix3i(fix(1),fix(0),fix(0)) && v0[1] == fix3i(fix(0),fix(1),fix(0)) && v0[2] == fix3i(fix(0),fix(0),fix(1)))); + STATIC_CHECK((v1[0] == fix3i(fix(2),fix(0),fix(0)) && v1[1] == fix3i(fix(0),fix(2),fix(0)) && v1[2] == fix3i(fix(0),fix(0),fix(2)))); + STATIC_CHECK((v2[0] == fix3i(fix(1),fix(0),fix(0)) && v2[1] == fix3i(fix(0),fix(2),fix(0)) && v2[2] == fix3i(fix(0),fix(0),fix(3)))); + STATIC_CHECK((v3[0] == fix3i(fix(1),fix(2),fix(3)) && v3[1] == fix3i(fix(4),fix(5),fix(6)) && v3[2] == fix3i(fix(7),fix(8),fix(9)))); + STATIC_CHECK((v4[0] == fix3i(fix(1),fix(2),fix(3)) && v4[1] == fix3i(fix(4),fix(5),fix(6)) && v4[2] == fix3i(fix(7),fix(8),fix(9)))); + STATIC_CHECK((v5[0] == fix3i(fix(1),fix(0),fix(0)) && v5[1] == fix3i(fix(0),fix(1),fix(0)) && v5[2] == fix3i(fix(0),fix(0),fix(1)))); + STATIC_CHECK((v6[0] == fix3i(fix(1),fix(0),fix(0)) && v6[1] == fix3i(fix(0),fix(1),fix(0)) && v6[2] == fix3i(fix(0),fix(0),fix(1)))); + STATIC_CHECK((v7[0] == fix3i(fix(1),fix(0),fix(0)) && v7[1] == fix3i(fix(0),fix(1),fix(0)) && v7[2] == fix3i(fix(0),fix(0),fix(1)))); + } + + SUBCASE("fix4x4 ctors") { + constexpr fix4x4i v0{}; + constexpr fix4x4i v1{fix(2)}; + constexpr fix4x4i v2{fix4i{fix(1),fix(2),fix(3),fix(4)}}; + constexpr fix4x4i v3{fix(1),fix(2),fix(3),fix(4),fix(5),fix(6),fix(7),fix(8),fix(9),fix(10),fix(11),fix(12),fix(13),fix(14),fix(15),fix(16)}; + constexpr fix4x4i v4{{fix(1),fix(2),fix(3),fix(4)},{fix(5),fix(6),fix(7),fix(8)},{fix(9),fix(10),fix(11),fix(12)},{fix(13),fix(14),fix(15),fix(16)}}; + constexpr fix4x4i v5{fix3x3i{fix(1)},fix3i{fix(0)}}; + constexpr fix4x4i v6{fix2x2i{fix(1)}}; + constexpr fix4x4i v7{fix3x3i{fix(1)}}; + + STATIC_CHECK((v0[0] == fix4i(fix(1),fix(0),fix(0),fix(0)) && v0[1] == fix4i(fix(0),fix(1),fix(0),fix(0)) && v0[2] == fix4i(fix(0),fix(0),fix(1),fix(0)) && v0[3] == fix4i(fix(0),fix(0),fix(0),fix(1)))); + STATIC_CHECK((v1[0] == fix4i(fix(2),fix(0),fix(0),fix(0)) && v1[1] == fix4i(fix(0),fix(2),fix(0),fix(0)) && v1[2] == fix4i(fix(0),fix(0),fix(2),fix(0)) && v1[3] == fix4i(fix(0),fix(0),fix(0),fix(2)))); + STATIC_CHECK((v2[0] == fix4i(fix(1),fix(0),fix(0),fix(0)) && v2[1] == fix4i(fix(0),fix(2),fix(0),fix(0)) && v2[2] == fix4i(fix(0),fix(0),fix(3),fix(0)) && v2[3] == fix4i(fix(0),fix(0),fix(0),fix(4)))); + STATIC_CHECK((v3[0] == fix4i(fix(1),fix(2),fix(3),fix(4)) && v3[1] == fix4i(fix(5),fix(6),fix(7),fix(8)) && v3[2] == fix4i(fix(9),fix(10),fix(11),fix(12)) && v3[3] == fix4i(fix(13),fix(14),fix(15),fix(16)))); + STATIC_CHECK((v4[0] == fix4i(fix(1),fix(2),fix(3),fix(4)) && v4[1] == fix4i(fix(5),fix(6),fix(7),fix(8)) && v4[2] == fix4i(fix(9),fix(10),fix(11),fix(12)) && v4[3] == fix4i(fix(13),fix(14),fix(15),fix(16)))); + STATIC_CHECK((v5[0] == fix4i(fix(1),fix(0),fix(0),fix(0)) && v5[1] == fix4i(fix(0),fix(1),fix(0),fix(0)) && v5[2] == fix4i(fix(0),fix(0),fix(1),fix(0)) && v5[3] == fix4i(fix(0),fix(0),fix(0),fix(1)))); + STATIC_CHECK((v6[0] == fix4i(fix(1),fix(0),fix(0),fix(0)) && v6[1] == fix4i(fix(0),fix(1),fix(0),fix(0)) && v6[2] == fix4i(fix(0),fix(0),fix(1),fix(0)) && v6[3] == fix4i(fix(0),fix(0),fix(0),fix(1)))); + STATIC_CHECK((v7[0] == fix4i(fix(1),fix(0),fix(0),fix(0)) && v7[1] == fix4i(fix(0),fix(1),fix(0),fix(0)) && v7[2] == fix4i(fix(0),fix(0),fix(1),fix(0)) && v7[3] == fix4i(fix(0),fix(0),fix(0),fix(1)))); + } + + SUBCASE("swap") { + { + fix2x2i v0{fix(1)}; + fix2x2i v1{fix(2)}; + swap(v0, v1); + CHECK(v0 == fix2x2i(fix(2))); + CHECK(v1 == fix2x2i(fix(1))); + } + { + fix3x3i v0{fix(1)}; + fix3x3i v1{fix(2)}; + swap(v0, v1); + CHECK(v0 == fix3x3i(fix(2))); + CHECK(v1 == fix3x3i(fix(1))); + } + { + fix4x4i v0{fix(1)}; + fix4x4i v1{fix(2)}; + swap(v0, v1); + CHECK(v0 == fix4x4i(fix(2))); + CHECK(v1 == fix4x4i(fix(1))); + } + } + + SUBCASE("operators") { + fix2x2b mb{}; + fix2x2i mi{}; + fix2i vi{}; + bool b{}; + + mi = {+fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mi = {-fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mi = {~fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mb = {!fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} + fix{3}}; + mi = {fix{3} + fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} + fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} - fix{3}}; + mi = {fix{3} - fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} - fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} * fix{3}}; + mi = {fix{3} * fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + vi = {vi * mi}; + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} * fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} / fix{3}}; + mi = {fix{3} / fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + // mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} / fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} & fix{3}}; + mi = {fix{3} & fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} & fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} | fix{3}}; + mi = {fix{3} | fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} | fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} ^ fix{3}}; + mi = {fix{3} ^ fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mi = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} ^ fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + mb = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} && fix{3}}; + mb = {fix{3} && fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mb = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} && fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + mb = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} || fix{3}}; + mb = {fix{3} || fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + mb = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} || fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + b = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} == fix2x2i{fix(3),fix(4),fix(5),fix(6)}}; + b = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} != fix2x2i{fix(3),fix(4),fix(5),fix(6)}}; + b = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} < fix2x2i{fix(3),fix(4),fix(5),fix(6)}}; + + { + mi = {mi += fix{3}}; + mi = {mi += fix2x2i{fix(4),fix(5),fix(6),fix(7)}}; + mi = {mi -= fix{3}}; + mi = {mi -= fix2x2i{fix(4),fix(5),fix(6),fix(7)}}; + mi = {mi *= fix{3}}; + vi = {vi *= fix2x2i{fix(4),fix(5),fix(6),fix(7)}}; + mi = {mi *= fix2x2i{fix(4),fix(5),fix(6),fix(7)}}; + mi = {mi /= fix{3}}; + //mi = {mi /= fix2x2i{fix(4),fix(5),fix(6),fix(7)}}; + mi = {mi &= fix{3}}; + mi = {mi &= fix2x2i{fix(4),fix(5),fix(6),fix(7)}}; + mi = {mi |= fix{3}}; + mi = {mi |= fix2x2i{fix(4),fix(5),fix(6),fix(7)}}; + mi = {mi ^= fix{3}}; + mi = {mi ^= fix2x2i{fix(4),fix(5),fix(6),fix(7)}}; + } + } +} + +// +// fix_qua +// + +TEST_CASE("vmath/fix_qua") { + SUBCASE("ctors") { + constexpr qfix v0{}; + constexpr qfix v1{fix(1.f), fix(2.f), fix(3.f), fix(4.f)}; + constexpr qfix v2{fix3f{fix(1.f), fix(2.f), fix(3.f)}, fix(4.f)}; + constexpr qfix v3{fix4f{fix(1.f), fix(2.f), fix(3.f), fix(4.f)}}; + + STATIC_CHECK((v0.at(0) == fix(0.f))); + STATIC_CHECK((v1.at(0) == fix(1.f) && v1.at(1) == fix(2.f) && v1.at(2) == fix(3.f) && v1.at(3) == fix(4.f))); + STATIC_CHECK((v2.at(0) == fix(1.f) && v2.at(1) == fix(2.f) && v2.at(2) == fix(3.f) && v2.at(3) == fix(4.f))); + STATIC_CHECK((v3.at(0) == fix(1.f) && v3.at(1) == fix(2.f) && v3.at(2) == fix(3.f) && v3.at(3) == fix(4.f))); + } + + SUBCASE("swap") { + qfix v0{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}; + qfix v1{fix(4.f),fix(3.f),fix(2.f),fix(1.f)}; + swap(v0, v1); + CHECK(v0 == qfix(fix(4.f),fix(3.f),fix(2.f),fix(1.f))); + CHECK(v1 == qfix(fix(1.f),fix(2.f),fix(3.f),fix(4.f))); + } + + SUBCASE("operators") { + qfix qf; + fix3f vf; + bool b{}; + + qf = {+qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + qf = {-qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + + qf = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} + qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + qf = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} - qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + qf = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} * fix{1.f}}; + qf = {fix{1.f} * qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + vf = {fix3f{fix(1.f),fix(2.f),fix(3.f)} * qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + qf = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} * qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + qf = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} / fix{1.f}}; + qf = {fix{1.f} / qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + + qf = {qf += qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + qf = {qf -= qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + qf = {qf *= fix{1.f}}; + vf = {vf *= qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + qf = {qf *= qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + qf = {qf /= fix{1.f}}; + + b = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} == qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + b = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} != qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + b = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} < qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + } +} + +// +// Units +// + +TEST_CASE("vmath/fix_units") { + { + STATIC_CHECK(zero2> == fix2f{fix(0.f),fix(0.f)}); + STATIC_CHECK(zero3> == fix3f{fix(0.f),fix(0.f),fix(0.f)}); + STATIC_CHECK(zero4> == fix4f{fix(0.f),fix(0.f),fix(0.f),fix(0.f)}); + } + { + STATIC_CHECK(unit2> == fix2f{fix(1.f),fix(1.f)}); + STATIC_CHECK(unit3> == fix3f{fix(1.f),fix(1.f),fix(1.f)}); + STATIC_CHECK(unit4> == fix4f{fix(1.f),fix(1.f),fix(1.f),fix(1.f)}); + } + { + STATIC_CHECK(unit2_x> == fix2f{fix(1.f),fix(0.f)}); + STATIC_CHECK(unit2_y> == fix2f{fix(0.f),fix(1.f)}); + + STATIC_CHECK(unit3_x> == fix3f{fix(1.f),fix(0.f),fix(0.f)}); + STATIC_CHECK(unit3_y> == fix3f{fix(0.f),fix(1.f),fix(0.f)}); + STATIC_CHECK(unit3_z> == fix3f{fix(0.f),fix(0.f),fix(1.f)}); + + STATIC_CHECK(unit4_x> == fix4f{fix(1.f),fix(0.f),fix(0.f),fix(0.f)}); + STATIC_CHECK(unit4_y> == fix4f{fix(0.f),fix(1.f),fix(0.f),fix(0.f)}); + STATIC_CHECK(unit4_z> == fix4f{fix(0.f),fix(0.f),fix(1.f),fix(0.f)}); + STATIC_CHECK(unit4_w> == fix4f{fix(0.f),fix(0.f),fix(0.f),fix(1.f)}); + } + { + STATIC_CHECK(zero2x2> == fix2x2f{ + fix(0.f),fix(0.f), + fix(0.f),fix(0.f)}); + STATIC_CHECK(zero3x3> == fix3x3f{ + fix(0.f),fix(0.f),fix(0.f), + fix(0.f),fix(0.f),fix(0.f), + fix(0.f),fix(0.f),fix(0.f)}); + STATIC_CHECK(zero4x4> == fix4x4f{ + fix(0.f),fix(0.f),fix(0.f),fix(0.f), + fix(0.f),fix(0.f),fix(0.f),fix(0.f), + fix(0.f),fix(0.f),fix(0.f),fix(0.f), + fix(0.f),fix(0.f),fix(0.f),fix(0.f)}); + } + { + STATIC_CHECK(unit2x2> == fix2x2f{ + fix(1.f),fix(1.f), + fix(1.f),fix(1.f)}); + STATIC_CHECK(unit3x3> == fix3x3f{ + fix(1.f),fix(1.f),fix(1.f), + fix(1.f),fix(1.f),fix(1.f), + fix(1.f),fix(1.f),fix(1.f)}); + STATIC_CHECK(unit4x4> == fix4x4f{ + fix(1.f),fix(1.f),fix(1.f),fix(1.f), + fix(1.f),fix(1.f),fix(1.f),fix(1.f), + fix(1.f),fix(1.f),fix(1.f),fix(1.f), + fix(1.f),fix(1.f),fix(1.f),fix(1.f)}); + } + { + STATIC_CHECK(identity2x2> == fix2x2f{ + fix(1.f),fix(0.f), + fix(0.f),fix(1.f)}); + STATIC_CHECK(identity3x3> == fix3x3f{ + fix(1.f),fix(0.f),fix(0.f), + fix(0.f),fix(1.f),fix(0.f), + fix(0.f),fix(0.f),fix(1.f)}); + STATIC_CHECK(identity4x4> == fix4x4f{ + fix(1.f),fix(0.f),fix(0.f),fix(0.f), + fix(0.f),fix(1.f),fix(0.f),fix(0.f), + fix(0.f),fix(0.f),fix(1.f),fix(0.f), + fix(0.f),fix(0.f),fix(0.f),fix(1.f)}); + } + { + STATIC_CHECK(qidentity> == qfix{ + fix(0.f),fix(0.f),fix(0.f), + fix(1.f)}); + } +} From 5c800b1ce60f4d4926539c5679477f2be13e1483 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Sun, 21 Feb 2021 02:07:27 +0700 Subject: [PATCH 08/15] warning fixes --- headers/vmath.hpp/vmath_ext.hpp | 16 +-- headers/vmath.hpp/vmath_fun.hpp | 4 +- headers/vmath.hpp/vmath_qua_fun.hpp | 2 +- untests/vmath_fix_tests.cpp | 158 ++++++++++++++-------------- 4 files changed, 92 insertions(+), 88 deletions(-) diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index c462e90..2cd9b71 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -795,7 +795,7 @@ namespace vmath_hpp /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovlh - const T sy = rcp(tan(fovy * T{0.5})); + const T sy = rcp(tan(fovy * T{0.5f})); const T sx = sy * rcp(aspect); const T sz = zfar * rcp(zfar - znear); const T tz = (znear * zfar) * rcp(znear - zfar); @@ -812,7 +812,7 @@ namespace vmath_hpp /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh - const T sy = rcp(tan(fovy * T{0.5})); + const T sy = rcp(tan(fovy * T{0.5f})); const T sx = sy * rcp(aspect); const T sz = zfar * rcp(znear - zfar); const T tz = (znear * zfar) * rcp(znear - zfar); @@ -901,7 +901,7 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ - auto xyzw = T{0.5} * sqrt(max(T{0}, vec{ + auto xyzw = T{0.5f} * sqrt(max(T{0}, vec{ T{1} + m[0][0] - m[1][1] - m[2][2], T{1} - m[0][0] + m[1][1] - m[2][2], T{1} - m[0][0] - m[1][1] + m[2][2], @@ -927,7 +927,7 @@ namespace vmath_hpp const T n = sqrt(length2(from) * length2(to)); const T s = dot(from, to) + n; - if ( s < T{0.000001} * n ) { + if ( s < T{0.000001f} * n ) { return abs(from.z) < abs(from.x) ? normalize(qua{vec{-from.y, from.x, T{0}}, T{0}}) : normalize(qua{vec{T{0}, -from.z, from.y}, T{0}}); @@ -946,7 +946,7 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ - const auto [s, c] = sincos(angle * T{0.5}); + const auto [s, c] = sincos(angle * T{0.5f}); const auto [x, y, z] = normalize(axis); return {vec{x, y, z} * s, c}; @@ -962,7 +962,7 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ - const auto [s, c] = sincos(angle * T{0.5}); + const auto [s, c] = sincos(angle * T{0.5f}); return {vec{s, T{0}, T{0}}, c}; } @@ -977,7 +977,7 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ - const auto [s, c] = sincos(angle * T{0.5}); + const auto [s, c] = sincos(angle * T{0.5f}); return {vec{T{0}, s, T{0}}, c}; } @@ -992,7 +992,7 @@ namespace vmath_hpp /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ - const auto [s, c] = sincos(angle * T{0.5}); + const auto [s, c] = sincos(angle * T{0.5f}); return {vec{T{0}, T{0}, s}, c}; } diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index aa6b37f..65e87f0 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -151,13 +151,13 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr radians(T degrees) noexcept { - return degrees * T{0.01745329251994329576923690768489}; + return degrees * T(0.01745329251994329576923690768489); } template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr degrees(T radians) noexcept { - return radians * T{57.295779513082320876798154814105}; + return radians * T(57.295779513082320876798154814105); } template < typename T > diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index ea7b755..b6c32d5 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -183,7 +183,7 @@ namespace vmath_hpp const T raw_cos_theta_sign = sign(raw_cos_theta); // half degree linear threshold: cos((pi / 180) * 0.25) - if ( const T cos_theta = raw_cos_theta * raw_cos_theta_sign; cos_theta < T{0.99999} ) { + if ( const T cos_theta = raw_cos_theta * raw_cos_theta_sign; cos_theta < T{0.99999f} ) { const T theta = acos(cos_theta); const T rsin_theta = rsqrt(T{1} - sqr(cos_theta)); const T xs_scale = sin((T{1} - a) * theta) * rsin_theta; diff --git a/untests/vmath_fix_tests.cpp b/untests/vmath_fix_tests.cpp index d20ace1..5baa823 100644 --- a/untests/vmath_fix_tests.cpp +++ b/untests/vmath_fix_tests.cpp @@ -8,9 +8,6 @@ namespace { - using namespace vmath_hpp; - using namespace vmath_tests; - template < typename T > class fix { public: @@ -25,76 +22,76 @@ namespace constexpr explicit fix(T underlying): underlying_(underlying) {} constexpr T underlying() const noexcept { return underlying_; } - constexpr friend fix abs(const fix& l) { return { fix{abs(l.underlying())} }; } - constexpr friend fix sqr(const fix& l) { return { fix{sqr(l.underlying())} }; } - constexpr friend fix sign(const fix& l) { return { fix{sign(l.underlying())} }; } + constexpr friend fix abs(const fix& l) { using vmath_hpp::abs; return { fix{abs(l.underlying())} }; } + constexpr friend fix sqr(const fix& l) { using vmath_hpp::sqr; return { fix{sqr(l.underlying())} }; } + constexpr friend fix sign(const fix& l) { using vmath_hpp::sign; return { fix{sign(l.underlying())} }; } - constexpr friend fix rcp(const fix& l) { return { fix{rcp(l.underlying())} }; } - constexpr friend fix floor(const fix& l) { return { fix{floor(l.underlying())} }; } - constexpr friend fix trunc(const fix& l) { return { fix{trunc(l.underlying())} }; } - constexpr friend fix round(const fix& l) { return { fix{round(l.underlying())} }; } - constexpr friend fix ceil(const fix& l) { return { fix{ceil(l.underlying())} }; } - constexpr friend fix fract(const fix& l) { return { fix{fract(l.underlying())} }; } + constexpr friend fix rcp(const fix& l) { using vmath_hpp::rcp; return { fix{rcp(l.underlying())} }; } + constexpr friend fix floor(const fix& l) { using vmath_hpp::floor; return { fix{floor(l.underlying())} }; } + constexpr friend fix trunc(const fix& l) { using vmath_hpp::trunc; return { fix{trunc(l.underlying())} }; } + constexpr friend fix round(const fix& l) { using vmath_hpp::round; return { fix{round(l.underlying())} }; } + constexpr friend fix ceil(const fix& l) { using vmath_hpp::ceil; return { fix{ceil(l.underlying())} }; } + constexpr friend fix fract(const fix& l) { using vmath_hpp::fract; return { fix{fract(l.underlying())} }; } - constexpr friend fix fmod(const fix& l, const fix& r) { return { fix{fmod(l.underlying(), r.underlying())} }; } - constexpr friend fix copysign(const fix& l, const fix& r) { return { fix{copysign(l.underlying(), r.underlying())} }; } + constexpr friend fix fmod(const fix& l, const fix& r) { using vmath_hpp::fmod; return { fix{fmod(l.underlying(), r.underlying())} }; } + constexpr friend fix copysign(const fix& l, const fix& r) { using vmath_hpp::copysign; return { fix{copysign(l.underlying(), r.underlying())} }; } - constexpr friend fix min(const fix& l, const fix& r) { return fix{min(l.underlying(), r.underlying())}; } - constexpr friend fix max(const fix& l, const fix& r) { return fix{max(l.underlying(), r.underlying())}; } - constexpr friend fix clamp(const fix& l, const fix& min_l, const fix& max_l) { return fix{clamp(l.underlying(), min_l.underlying(), max_l.underlying())}; } - constexpr friend fix saturate(const fix& l) { return fix{saturate(l.underlying())}; } - constexpr friend fix lerp(const fix& l, const fix& r, const fix& a) { return fix{lerp(l.underlying(), r.underlying(), a.underlying())}; } - constexpr friend fix lerp(const fix& l, const fix& r, const fix& a, const fix& b) { return fix{lerp(l.underlying(), r.underlying(), a.underlying(), b.underlying())}; } + constexpr friend fix min(const fix& l, const fix& r) { using vmath_hpp::min; return fix{min(l.underlying(), r.underlying())}; } + constexpr friend fix max(const fix& l, const fix& r) { using vmath_hpp::max; return fix{max(l.underlying(), r.underlying())}; } + constexpr friend fix clamp(const fix& l, const fix& min_l, const fix& max_l) { using vmath_hpp::clamp; return fix{clamp(l.underlying(), min_l.underlying(), max_l.underlying())}; } + constexpr friend fix saturate(const fix& l) { using vmath_hpp::saturate; return fix{saturate(l.underlying())}; } + constexpr friend fix lerp(const fix& l, const fix& r, const fix& a) { using vmath_hpp::lerp; return fix{lerp(l.underlying(), r.underlying(), a.underlying())}; } + constexpr friend fix lerp(const fix& l, const fix& r, const fix& a, const fix& b) { using vmath_hpp::lerp; return fix{lerp(l.underlying(), r.underlying(), a.underlying(), b.underlying())}; } - constexpr friend fix step(const fix& e, const fix& l) { return fix{step(e.underlying(), l.underlying())}; } - constexpr friend fix smoothstep(const fix& e0, const fix& e1, const fix& l) { return fix{smoothstep(e0.underlying(), e1.underlying(), l.underlying())}; } + constexpr friend fix step(const fix& e, const fix& l) { using vmath_hpp::step; return fix{step(e.underlying(), l.underlying())}; } + constexpr friend fix smoothstep(const fix& e0, const fix& e1, const fix& l) { using vmath_hpp::smoothstep; return fix{smoothstep(e0.underlying(), e1.underlying(), l.underlying())}; } - constexpr friend fix fma(const fix& x, const fix& y, const fix& z) { return fix{fma(x.underlying(), y.underlying(), z.underlying())}; } + constexpr friend fix fma(const fix& x, const fix& y, const fix& z) { using vmath_hpp::fma; return fix{fma(x.underlying(), y.underlying(), z.underlying())}; } // - constexpr friend fix any(const fix& l) { return fix{any(l.underlying())}; } - constexpr friend fix all(const fix& l) { return fix{all(l.underlying())}; } + constexpr friend fix any(const fix& l) { using vmath_hpp::any; return fix{any(l.underlying())}; } + constexpr friend fix all(const fix& l) { using vmath_hpp::all; return fix{all(l.underlying())}; } - constexpr friend fix approx(const fix& l, const fix& r) { return fix{approx(l.underlying(), r.underlying())}; } - constexpr friend fix approx(const fix& l, const fix& r, const fix& e) { return fix{approx(l.underlying(), r.underlying(), e.underlying())}; } + constexpr friend fix approx(const fix& l, const fix& r) { using vmath_hpp::approx; return fix{approx(l.underlying(), r.underlying())}; } + constexpr friend fix approx(const fix& l, const fix& r, const fix& e) { using vmath_hpp::approx; return fix{approx(l.underlying(), r.underlying(), e.underlying())}; } - constexpr friend fix less(const fix& l, const fix& r) { return fix{less(l.underlying(), r.underlying())}; } - constexpr friend fix less_equal(const fix& l, const fix& r) { return fix{less_equal(l.underlying(), r.underlying())}; } - constexpr friend fix greater(const fix& l, const fix& r) { return fix{greater(l.underlying(), r.underlying())}; } - constexpr friend fix greater_equal(const fix& l, const fix& r) { return fix{greater_equal(l.underlying(), r.underlying())}; } - constexpr friend fix equal_to(const fix& l, const fix& r) { return fix{equal_to(l.underlying(), r.underlying())}; } - constexpr friend fix not_equal_to(const fix& l, const fix& r) { return fix{not_equal_to(l.underlying(), r.underlying())}; } + constexpr friend fix less(const fix& l, const fix& r) { using vmath_hpp::less; return fix{less(l.underlying(), r.underlying())}; } + constexpr friend fix less_equal(const fix& l, const fix& r) { using vmath_hpp::less_equal; return fix{less_equal(l.underlying(), r.underlying())}; } + constexpr friend fix greater(const fix& l, const fix& r) { using vmath_hpp::greater; return fix{greater(l.underlying(), r.underlying())}; } + constexpr friend fix greater_equal(const fix& l, const fix& r) { using vmath_hpp::greater_equal; return fix{greater_equal(l.underlying(), r.underlying())}; } + constexpr friend fix equal_to(const fix& l, const fix& r) { using vmath_hpp::equal_to; return fix{equal_to(l.underlying(), r.underlying())}; } + constexpr friend fix not_equal_to(const fix& l, const fix& r) { using vmath_hpp::not_equal_to; return fix{not_equal_to(l.underlying(), r.underlying())}; } // - constexpr friend fix radians(const fix& l) { return fix{radians(l.underlying())}; } - constexpr friend fix degrees(const fix& l) { return fix{degrees(l.underlying())}; } - friend fix sin(const fix& l) { return fix{sin(l.underlying())}; } - friend fix cos(const fix& l) { return fix{cos(l.underlying())}; } - friend fix tan(const fix& l) { return fix{tan(l.underlying())}; } - friend fix asin(const fix& l) { return fix{asin(l.underlying())}; } - friend fix acos(const fix& l) { return fix{acos(l.underlying())}; } - friend fix atan(const fix& l) { return fix{atan(l.underlying())}; } - friend fix atan2(const fix& l, const fix& r) { return fix{atan2(l.underlying(), r.underlying())}; } - friend fix sinh(const fix& l) { return fix{sinh(l.underlying())}; } - friend fix cosh(const fix& l) { return fix{cosh(l.underlying())}; } - friend fix tanh(const fix& l) { return fix{tanh(l.underlying())}; } - friend fix asinh(const fix& l) { return fix{asinh(l.underlying())}; } - friend fix acosh(const fix& l) { return fix{acosh(l.underlying())}; } - friend fix atanh(const fix& l) { return fix{atanh(l.underlying())}; } + constexpr friend fix radians(const fix& l) { using vmath_hpp::radians; return fix{radians(l.underlying())}; } + constexpr friend fix degrees(const fix& l) { using vmath_hpp::degrees; return fix{degrees(l.underlying())}; } + friend fix sin(const fix& l) { using vmath_hpp::sin; return fix{sin(l.underlying())}; } + friend fix cos(const fix& l) { using vmath_hpp::cos; return fix{cos(l.underlying())}; } + friend fix tan(const fix& l) { using vmath_hpp::tan; return fix{tan(l.underlying())}; } + friend fix asin(const fix& l) { using vmath_hpp::asin; return fix{asin(l.underlying())}; } + friend fix acos(const fix& l) { using vmath_hpp::acos; return fix{acos(l.underlying())}; } + friend fix atan(const fix& l) { using vmath_hpp::atan; return fix{atan(l.underlying())}; } + friend fix atan2(const fix& l, const fix& r) { using vmath_hpp::atan2; return fix{atan2(l.underlying(), r.underlying())}; } + friend fix sinh(const fix& l) { using vmath_hpp::sinh; return fix{sinh(l.underlying())}; } + friend fix cosh(const fix& l) { using vmath_hpp::cosh; return fix{cosh(l.underlying())}; } + friend fix tanh(const fix& l) { using vmath_hpp::tanh; return fix{tanh(l.underlying())}; } + friend fix asinh(const fix& l) { using vmath_hpp::asinh; return fix{asinh(l.underlying())}; } + friend fix acosh(const fix& l) { using vmath_hpp::acosh; return fix{acosh(l.underlying())}; } + friend fix atanh(const fix& l) { using vmath_hpp::atanh; return fix{atanh(l.underlying())}; } friend std::pair sincos(const fix& l) { return { sin(l), cos(l) }; } friend void sincos(const fix& l, fix* s, fix* c) { *s = sin(l); *c = cos(l); } // - friend fix pow(const fix& l, const fix& r) { return fix{pow(l.underlying(), r.underlying())}; } - friend fix exp(const fix& l) { return fix{exp(l.underlying())}; } - friend fix log(const fix& l) { return fix{log(l.underlying())}; } - friend fix exp2(const fix& l) { return fix{exp2(l.underlying())}; } - friend fix log2(const fix& l) { return fix{log2(l.underlying())}; } - friend fix sqrt(const fix& l) { return fix{sqrt(l.underlying())}; } - friend fix rsqrt(const fix& l) { return fix{rsqrt(l.underlying())}; } + friend fix pow(const fix& l, const fix& r) { using vmath_hpp::pow; return fix{pow(l.underlying(), r.underlying())}; } + friend fix exp(const fix& l) { using vmath_hpp::exp; return fix{exp(l.underlying())}; } + friend fix log(const fix& l) { using vmath_hpp::log; return fix{log(l.underlying())}; } + friend fix exp2(const fix& l) { using vmath_hpp::exp2; return fix{exp2(l.underlying())}; } + friend fix log2(const fix& l) { using vmath_hpp::log2; return fix{log2(l.underlying())}; } + friend fix sqrt(const fix& l) { using vmath_hpp::sqrt; return fix{sqrt(l.underlying())}; } + friend fix rsqrt(const fix& l) { using vmath_hpp::rsqrt; return fix{rsqrt(l.underlying())}; } // @@ -122,6 +119,9 @@ namespace T underlying_{}; }; + using namespace vmath_hpp; + using namespace vmath_tests; + using qfix = qua>; using fix2b = vec, 2>; @@ -629,27 +629,27 @@ TEST_CASE("vmath/fix_vec") { vb = {fix{3} || fix2i{fix(1),fix(2)}}; vb = {fix2i{fix(1),fix(2)} || fix2i{fix(1),fix(2)}}; - b = {fix2i{fix(1),fix(2)} == fix2i{fix(3),fix(4)}}; - b = {fix2i{fix(1),fix(2)} != fix2i{fix(3),fix(4)}}; - b = {fix2i{fix(1),fix(2)} < fix2i{fix(3),fix(4)}}; + b = {fix2i{fix(1),fix(2)} == fix2i{fix(1),fix(2)}}; + b = {fix2i{fix(1),fix(2)} != fix2i{fix(1),fix(2)}}; + b = {fix2i{fix(1),fix(2)} < fix2i{fix(1),fix(2)}}; + + CHECK_FALSE(b); { - fix2i v{}; - fix2i vi{}; - vi = {v += fix{3}}; - vi = {v += fix2i{fix(4),fix(5)}}; - vi = {v -= fix{3}}; - vi = {v -= fix2i{fix(4),fix(5)}}; - vi = {v *= fix{3}}; - vi = {v *= fix2i{fix(4),fix(5)}}; - vi = {v /= fix{3}}; - vi = {v /= fix2i{fix(4),fix(5)}}; - vi = {v &= fix{3}}; - vi = {v &= fix2i{fix(4),fix(5)}}; - vi = {v |= fix{3}}; - vi = {v |= fix2i{fix(4),fix(5)}}; - vi = {v ^= fix{3}}; - vi = {v ^= fix2i{fix(4),fix(5)}}; + vi = {vi += fix{3}}; + vi = {vi += fix2i{fix(4),fix(5)}}; + vi = {vi -= fix{3}}; + vi = {vi -= fix2i{fix(4),fix(5)}}; + vi = {vi *= fix{3}}; + vi = {vi *= fix2i{fix(4),fix(5)}}; + vi = {vi /= fix{3}}; + vi = {vi /= fix2i{fix(4),fix(5)}}; + vi = {vi &= fix{3}}; + vi = {vi &= fix2i{fix(4),fix(5)}}; + vi = {vi |= fix{3}}; + vi = {vi |= fix2i{fix(4),fix(5)}}; + vi = {vi ^= fix{3}}; + vi = {vi ^= fix2i{fix(4),fix(5)}}; } } } @@ -789,9 +789,11 @@ TEST_CASE("vmath/fix_mat") { mb = {fix{3} || fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; mb = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} || fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; - b = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} == fix2x2i{fix(3),fix(4),fix(5),fix(6)}}; - b = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} != fix2x2i{fix(3),fix(4),fix(5),fix(6)}}; - b = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} < fix2x2i{fix(3),fix(4),fix(5),fix(6)}}; + b = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} == fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + b = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} != fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + b = {fix2x2i{fix(1),fix(2),fix(3),fix(4)} < fix2x2i{fix(1),fix(2),fix(3),fix(4)}}; + + CHECK_FALSE(b); { mi = {mi += fix{3}}; @@ -865,6 +867,8 @@ TEST_CASE("vmath/fix_qua") { b = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} == qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; b = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} != qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; b = {qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)} < qfix{fix(1.f),fix(2.f),fix(3.f),fix(4.f)}}; + + CHECK_FALSE(b); } } From 2bded8a680e1bcdf40ad9623a8b425cafe57b32a Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 23 Feb 2021 10:00:16 +0700 Subject: [PATCH 09/15] some style fixes --- README.md | 51 ++++++----- headers/vmath.hpp/vmath_ext.hpp | 8 +- headers/vmath.hpp/vmath_fun.hpp | 14 ++-- headers/vmath.hpp/vmath_mat.hpp | 39 ++++----- headers/vmath.hpp/vmath_mat_fun.hpp | 126 +++++++++++----------------- headers/vmath.hpp/vmath_qua.hpp | 96 +++++++++++---------- headers/vmath.hpp/vmath_qua_fun.hpp | 51 ++++++++++- headers/vmath.hpp/vmath_vec.hpp | 20 +++-- headers/vmath.hpp/vmath_vec_fun.hpp | 115 +++++++------------------ untests/vmath_vec_fun_tests.cpp | 22 +++-- 10 files changed, 267 insertions(+), 275 deletions(-) diff --git a/README.md b/README.md index 2b00337..6c284cc 100644 --- a/README.md +++ b/README.md @@ -91,8 +91,6 @@ public: constexpr vec_base() = default; constexpr explicit vec_base(T v); constexpr vec_base(T x, T y); - constexpr explicit vec_base(const vec_base& xy); - constexpr explicit vec_base(const vec_base& xy); }; template < typename T > @@ -107,7 +105,8 @@ public: constexpr vec_base(T x, T y, T z); constexpr vec_base(const vec_base& xy, T z); constexpr vec_base(T x, const vec_base& yz); - constexpr explicit vec_base(const vec_base& xyz); + + constexpr explicit operator vec() const; }; template < typename T > @@ -127,12 +126,16 @@ public: constexpr vec_base(const vec_base& xy, const vec_base& zw); constexpr vec_base(const vec_base& xyz, T w); constexpr vec_base(T x, const vec_base& yzw); + + constexpr explicit operator vec() const; + constexpr explicit operator vec() const; }; template < typename T, size_t Size > class vec final : public vec_base { public: using self_type = vec; + using base_type = vec_base; using component_type = T; using pointer = component_type*; @@ -234,9 +237,6 @@ public: constexpr mat_base( const row_type& row0, const row_type& row1); - - constexpr explicit mat_base(const mat_base& other); - constexpr explicit mat_base(const mat_base& other); }; template < typename T > @@ -268,7 +268,8 @@ public: const vec_base& v); constexpr explicit mat_base(const mat_base& other); - constexpr explicit mat_base(const mat_base& other); + + constexpr explicit operator mat() const; }; template < typename T > @@ -304,12 +305,18 @@ public: constexpr explicit mat_base(const mat_base& other); constexpr explicit mat_base(const mat_base& other); + + constexpr explicit operator mat() const; + constexpr explicit operator mat() const; }; template < typename T, size_t Size > class mat final : public mat_base { public: using self_type = mat; + using base_type = mat_base; + using component_type = T; + using row_type = vec; using pointer = row_type*; @@ -388,18 +395,30 @@ using ptrdiff4x4_t = mat; ### Quaternion Types ```cpp +template < typename T > +class qua_base { +public: + vec v = vec{T{0}}; + T s = T{1}; + + constexpr qua_base(); + constexpr qua_base(T vx, T vy, T vz, T s); + constexpr qua_base(const vec& v, T s); + + constexpr explicit qua_base(const vec& vs); + constexpr explicit operator vec() const; +}; + template < typename T > class qua final { public: + using self_type = qua; + using base_type = qua_base; + using component_type = T; + using imag_type = vec; using real_type = T; - imag_type v = imag_type{T{0}}; - real_type s = real_type{T{1}}; -public: - using self_type = qua; - using component_type = T; - using pointer = component_type*; using const_pointer = const component_type*; @@ -417,12 +436,6 @@ public: constexpr qua(const qua&) = default; constexpr qua& operator=(const qua&) = default; - constexpr qua(T vx, T vy, T vz, T s); - constexpr qua(const vec& v, T s); - constexpr explicit qua(const vec& vs); - - constexpr explicit operator vec() const; - void swap(qua& other) noexcept(is_nothrow_swappable_v); iterator begin() noexcept; diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index 2cd9b71..e67a9ea 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -112,7 +112,7 @@ namespace vmath_hpp::detail template < typename T > [[nodiscard]] std::size_t hash(const qua& q) noexcept { - return hash(vec{q}); + return fold_join(hash_combiner{}, std::size_t{}, q); } } @@ -156,17 +156,17 @@ namespace vmath_hpp template < typename To, typename From, std::size_t Size > [[nodiscard]] constexpr vec cast_to(const vec& v) { - return detail::map_join([](From x){ return cast_to(x); }, v); + return map_join([](From x){ return cast_to(x); }, v); } template < typename To, typename From, std::size_t Size > [[nodiscard]] constexpr mat cast_to(const mat& m) { - return detail::map_join([](const vec& v){ return cast_to(v); }, m); + return map_join([](const vec& v){ return cast_to(v); }, m); } template < typename To, typename From > [[nodiscard]] constexpr qua cast_to(const qua& q) { - return qua(cast_to(vec{q})); + return map_join([](From x){ return cast_to(x); }, q); } } diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index 65e87f0..e2ba837 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -15,15 +15,13 @@ namespace vmath_hpp { template < typename T > - [[nodiscard]] std::enable_if_t, T> + [[nodiscard]] std::enable_if_t, T> constexpr abs(T x) noexcept { - return x < T{0} ? -x : x; - } - - template < typename T > - [[nodiscard]] std::enable_if_t, T> - constexpr abs(T x) noexcept { - return x; + if constexpr ( std::is_signed_v ) { + return x < T{0} ? -x : x; + } else { + return x; + } } template < typename T > diff --git a/headers/vmath.hpp/vmath_mat.hpp b/headers/vmath.hpp/vmath_mat.hpp index d6c377a..182531e 100644 --- a/headers/vmath.hpp/vmath_mat.hpp +++ b/headers/vmath.hpp/vmath_mat.hpp @@ -48,18 +48,6 @@ namespace vmath_hpp::detail const row_type& row0, const row_type& row1) : rows{row0, row1} {} - - constexpr explicit mat_base( - const mat_base& other) - : rows{ - row_type{other.rows[0]}, - row_type{other.rows[1]}} {} - - constexpr explicit mat_base( - const mat_base& other) - : rows{ - row_type{other.rows[0]}, - row_type{other.rows[1]}} {} }; template < typename T > @@ -116,12 +104,11 @@ namespace vmath_hpp::detail row_type{other.rows[1], T{0}}, row_type{T{0}, T{0}, T{1}}} {} - constexpr explicit mat_base( - const mat_base& other) - : rows{ - row_type{other.rows[0]}, - row_type{other.rows[1]}, - row_type{other.rows[2]}} {} + constexpr explicit operator mat() const { + return { + vec{rows[0]}, + vec{rows[1]}}; + } }; template < typename T > @@ -193,6 +180,19 @@ namespace vmath_hpp::detail row_type{other.rows[1], T{0}}, row_type{other.rows[2], T{0}}, row_type{T{0}, T{0}, T{0}, T{1}}} {} + + constexpr explicit operator mat() const { + return { + vec{rows[0]}, + vec{rows[1]}}; + } + + constexpr explicit operator mat() const { + return { + vec{rows[0]}, + vec{rows[1]}, + vec{rows[2]}}; + } }; } @@ -203,7 +203,8 @@ namespace vmath_hpp public: using self_type = mat; using base_type = detail::mat_base; - public: + using component_type = T; + using row_type = vec; using pointer = row_type*; diff --git a/headers/vmath.hpp/vmath_mat_fun.hpp b/headers/vmath.hpp/vmath_mat_fun.hpp index 2f0e053..b44b485 100644 --- a/headers/vmath.hpp/vmath_mat_fun.hpp +++ b/headers/vmath.hpp/vmath_mat_fun.hpp @@ -18,88 +18,94 @@ namespace vmath_hpp::detail::impl { template < typename A, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( + mat + >::component_type, Size> + map_join_impl( F&& f, const mat& a, - std::index_sequence - ) -> mat>()))::component_type, Size> + std::index_sequence) { return { f(a[Is])... }; } template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( + mat, + vec + >::component_type, Size> + map_join_impl( F&& f, const mat& a, const mat& b, - std::index_sequence - ) -> mat>(), - std::declval>()))::component_type, Size> + std::index_sequence) { return { f(a[Is], b[Is])... }; } template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( + mat, + vec, + vec + >::component_type, Size> + map_join_impl( F&& f, const mat& a, const mat& b, const mat& c, - std::index_sequence - ) -> mat>(), - std::declval>(), - std::declval>()))::component_type, Size> + std::index_sequence) { return { f(a[Is], b[Is], c[Is])... }; } template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join_impl( + A fold_join_impl( F&& f, A init, const mat& b, - std::index_sequence - ) -> A { + std::index_sequence) + { return ((init = f(std::move(init), b[Is])), ...); } template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join_impl( + A fold_join_impl( F&& f, A init, const vec& b, const mat& c, - std::index_sequence - ) -> A { + std::index_sequence) + { return ((init = f(std::move(init), b[Is], c[Is])), ...); } template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join_impl( + A fold_join_impl( F&& f, A init, const mat& b, const mat& c, - std::index_sequence - ) -> A { + std::index_sequence) + { return ((init = f(std::move(init), b[Is], c[Is])), ...); } template < typename A, std::size_t Size, typename F, std::size_t I, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold1_join_impl( + vec fold1_join_impl( F&& f, const mat& a, - std::index_sequence - ) -> vec { + std::index_sequence) + { vec init = a[I]; return ((init = f(std::move(init), a[Is])), ...); } @@ -109,80 +115,44 @@ namespace vmath_hpp::detail { template < typename A, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join( - F&& f, - const mat& a - ) { - return impl::map_join_impl( - std::forward(f), a, std::make_index_sequence{}); + auto map_join(F&& f, const mat& a) { + return impl::map_join_impl(std::forward(f), a, std::make_index_sequence{}); } template < typename A, typename B, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join( - F&& f, - const mat& a, - const mat& b - ) { - return impl::map_join_impl( - std::forward(f), a, b, std::make_index_sequence{}); + auto map_join(F&& f, const mat& a, const mat& b) { + return impl::map_join_impl(std::forward(f), a, b, std::make_index_sequence{}); } template < typename A, typename B, typename C, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join( - F&& f, - const mat& a, - const mat& b, - const mat& c - ) { - return impl::map_join_impl( - std::forward(f), a, b, c, std::make_index_sequence{}); + auto map_join(F&& f, const mat& a, const mat& b, const mat& c) { + return impl::map_join_impl(std::forward(f), a, b, c, std::make_index_sequence{}); } template < typename A, typename B, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join( - F&& f, - A init, - const mat& b - ) { - return impl::fold_join_impl( - std::forward(f), std::move(init), b, std::make_index_sequence{}); + auto fold_join(F&& f, A init, const mat& b) { + return impl::fold_join_impl(std::forward(f), std::move(init), b, std::make_index_sequence{}); } template < typename A, typename B, typename C, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join( - F&& f, - A init, - const vec& b, - const mat& c - ) { - return impl::fold_join_impl( - std::forward(f), std::move(init), b, c, std::make_index_sequence{}); + auto fold_join(F&& f, A init, const vec& b, const mat& c) { + return impl::fold_join_impl(std::forward(f), std::move(init), b, c, std::make_index_sequence{}); } template < typename A, typename B, typename C, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join( - F&& f, - A init, - const mat& b, - const mat& c - ) { - return impl::fold_join_impl( - std::forward(f), std::move(init), b, c, std::make_index_sequence{}); + auto fold_join(F&& f, A init, const mat& b, const mat& c) { + return impl::fold_join_impl(std::forward(f), std::move(init), b, c, std::make_index_sequence{}); } template < typename A, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold1_join( - F&& f, - const mat& a - ) { - return impl::fold1_join_impl( - std::forward(f), a, std::make_index_sequence{}); + auto fold1_join(F&& f, const mat& a) { + return impl::fold1_join_impl(std::forward(f), a, std::make_index_sequence{}); } } @@ -196,7 +166,7 @@ namespace vmath_hpp template < typename T, std::size_t Size > [[nodiscard]] constexpr auto operator+(const mat& xs) { - return xs; + return map_join([](const vec& x){ return +x; }, xs); } // -operator diff --git a/headers/vmath.hpp/vmath_qua.hpp b/headers/vmath.hpp/vmath_qua.hpp index 9d955b8..dc66ed8 100644 --- a/headers/vmath.hpp/vmath_qua.hpp +++ b/headers/vmath.hpp/vmath_qua.hpp @@ -11,20 +11,63 @@ #include "vmath_vec.hpp" #include "vmath_vec_fun.hpp" +namespace vmath_hpp::detail +{ + template < typename T > + class qua_base { + public: + vec v = vec{T{0}}; + T s = T{1}; + public: + constexpr qua_base() = default; + + constexpr qua_base(T vx, T vy, T vz, T s) + : v{vx, vy, vz}, s{s} {} + + constexpr qua_base(const vec& v, T s) + : v{v}, s{s} {} + + constexpr explicit qua_base(const vec& vs) + : v{vs[0], vs[1], vs[2]}, s{vs[3]} {} + + constexpr explicit operator vec() const { + return {v, s}; + } + + [[nodiscard]] constexpr T& operator[](std::size_t index) noexcept { + switch ( index ) { + default: + case 0: return v.x; + case 1: return v.y; + case 2: return v.z; + case 3: return s; + } + } + + [[nodiscard]] constexpr const T& operator[](std::size_t index) const noexcept { + switch ( index ) { + default: + case 0: return v.x; + case 1: return v.y; + case 2: return v.z; + case 3: return s; + } + } + }; +} + namespace vmath_hpp { template < typename T > - class qua final { - public: - using imag_type = vec; - using real_type = T; - - imag_type v = imag_type{T{0}}; - real_type s = real_type{T{1}}; + class qua final : public detail::qua_base { public: using self_type = qua; + using base_type = detail::qua_base; using component_type = T; + using imag_type = vec; + using real_type = T; + using pointer = component_type*; using const_pointer = const component_type*; @@ -38,26 +81,13 @@ namespace vmath_hpp static constexpr std::size_t size = 4; public: + using base_type::qua_base; + using base_type::operator[]; + constexpr qua() = default; constexpr qua(const qua&) = default; constexpr qua& operator=(const qua&) = default; - constexpr qua(T vx, T vy, T vz, T s) - : v{vx, vy, vz} - , s{s} {} - - constexpr qua(const vec& v, T s) - : v{v} - , s{s} {} - - constexpr explicit qua(const vec& vs) - : v{vs[0], vs[1], vs[2]} - , s{vs[3]} {} - - constexpr explicit operator vec() const { - return {(*this).v, (*this).s}; - } - void swap(qua& other) noexcept(std::is_nothrow_swappable_v) { for ( std::size_t i = 0; i < size; ++i ) { using std::swap; @@ -97,26 +127,6 @@ namespace vmath_hpp VMATH_HPP_THROW_IF(index >= size, std::out_of_range("qua::at")); return (*this)[index]; } - - [[nodiscard]] constexpr reference operator[](std::size_t index) noexcept { - switch ( index ) { - default: - case 0: return v.x; - case 1: return v.y; - case 2: return v.z; - case 3: return s; - } - } - - [[nodiscard]] constexpr const_reference operator[](std::size_t index) const noexcept { - switch ( index ) { - default: - case 0: return v.x; - case 1: return v.y; - case 2: return v.z; - case 3: return s; - } - } }; } diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index b6c32d5..fac296d 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -14,6 +14,51 @@ #include "vmath_vec.hpp" #include "vmath_vec_fun.hpp" +namespace vmath_hpp::detail +{ + template < typename A, typename F > + [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE + auto map_join(F&& f, const qua& a) { + return qua(map_join(std::forward(f), vec{a})); + } + + template < typename A, typename B, typename F > + [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE + auto map_join(F&& f, const qua& a, const qua& b) { + return qua(map_join(std::forward(f), vec{a}, vec{b})); + } + + template < typename A, typename B, typename C, typename F > + [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE + auto map_join(F&& f, const qua& a, const qua& b, const qua& c) { + return qua(map_join(std::forward(f), vec{a}, vec{b}, vec{c})); + } + + template < typename A, typename B, typename C, typename D, typename F > + [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE + auto map_join(F&& f, const qua& a, const qua& b, const qua& c, const qua& d) { + return qua(map_join(std::forward(f), vec{a}, vec{b}, vec{c}, vec{d})); + } + + template < typename A, typename B, typename F > + [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE + auto fold_join(F&& f, A init, const qua& b) { + return fold_join(std::forward(f), std::move(init), vec{b}); + } + + template < typename A, typename B, typename C, typename F > + [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE + auto fold_join(F&& f, A init, const qua& b, const qua& c) { + return fold_join(std::forward(f), std::move(init), vec{b}, vec{c}); + } + + template < typename A, typename F > + [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE + auto fold1_join(F&& f, const qua& a) { + return fold1_join(std::forward(f), vec{a}); + } +} + // // Operators // @@ -24,7 +69,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] constexpr auto operator+(const qua& xs) { - return xs; + return qua(+vec{xs}); } // -operator @@ -163,8 +208,8 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] qua lerp(const qua& xs, const qua& ys, T xs_a, T ys_a) { - return qua(lerp(vec{xs}, vec{ys}, xs_a, ys_a)); + [[nodiscard]] qua lerp(const qua& xs, const qua& ys, T x_a, T y_a) { + return qua(lerp(vec{xs}, vec{ys}, x_a, y_a)); } template < typename T > diff --git a/headers/vmath.hpp/vmath_vec.hpp b/headers/vmath.hpp/vmath_vec.hpp index 36a6f13..896b6f9 100644 --- a/headers/vmath.hpp/vmath_vec.hpp +++ b/headers/vmath.hpp/vmath_vec.hpp @@ -27,12 +27,6 @@ namespace vmath_hpp::detail constexpr vec_base(T x, T y) : x{x}, y{y} {} - constexpr explicit vec_base(const vec_base& xy) - : x{xy[0]}, y{xy[1]} {} - - constexpr explicit vec_base(const vec_base& xy) - : x{xy[0]}, y{xy[1]} {} - [[nodiscard]] constexpr T& operator[](std::size_t index) noexcept { switch ( index ) { default: @@ -71,8 +65,9 @@ namespace vmath_hpp::detail constexpr vec_base(T x, const vec_base& yz) : x{x}, y{yz[0]}, z{yz[1]} {} - constexpr explicit vec_base(const vec_base& xyz) - : x{xyz[0]}, y{xyz[1]}, z{xyz[2]} {} + constexpr explicit operator vec() const { + return {x, y}; + } [[nodiscard]] constexpr T& operator[](std::size_t index) noexcept { switch ( index ) { @@ -127,6 +122,14 @@ namespace vmath_hpp::detail constexpr vec_base(T x, const vec_base& yzw) : x{x}, y{yzw[0]}, z{yzw[1]}, w{yzw[2]} {} + constexpr explicit operator vec() const { + return {x, y}; + } + + constexpr explicit operator vec() const { + return {x, y, z}; + } + [[nodiscard]] constexpr T& operator[](std::size_t index) noexcept { switch ( index ) { default: @@ -156,7 +159,6 @@ namespace vmath_hpp public: using self_type = vec; using base_type = detail::vec_base; - public: using component_type = T; using pointer = component_type*; diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 44817a0..951634e 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -15,94 +15,80 @@ namespace vmath_hpp::detail::impl { template < typename A, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( + vec, Size> map_join_impl( F&& f, const vec& a, - std::index_sequence - ) -> vec())), Size> + std::index_sequence) { return { f(a[Is])... }; } template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( + vec, Size> map_join_impl( F&& f, const vec& a, const vec& b, - std::index_sequence - ) -> vec(), - std::declval())), Size> + std::index_sequence) { return { f(a[Is], b[Is])... }; } template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( + vec, Size> map_join_impl( F&& f, const vec& a, const vec& b, const vec& c, - std::index_sequence - ) -> vec(), - std::declval(), - std::declval())), Size> + std::index_sequence) { return { f(a[Is], b[Is], c[Is])... }; } template < typename A, typename B, typename C, typename D, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( + vec, Size> map_join_impl( F&& f, const vec& a, const vec& b, const vec& c, const vec& d, - std::index_sequence - ) -> vec(), - std::declval(), - std::declval(), - std::declval())), Size> + std::index_sequence) { return { f(a[Is], b[Is], c[Is], d[Is])... }; } template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join_impl( + A fold_join_impl( F&& f, A init, const vec& b, - std::index_sequence - ) -> A { + std::index_sequence) + { return ((init = f(std::move(init), b[Is])), ...); } template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join_impl( + A fold_join_impl( F&& f, A init, const vec& b, const vec& c, - std::index_sequence - ) -> A { + std::index_sequence) + { return ((init = f(std::move(init), b[Is], c[Is])), ...); } template < typename A, std::size_t Size, typename F, std::size_t I, std::size_t... Is > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold1_join_impl( + A fold1_join_impl( F&& f, const vec& a, - std::index_sequence - ) -> A { + std::index_sequence) + { A init = a[I]; return ((init = f(std::move(init), a[Is])), ...); } @@ -112,81 +98,44 @@ namespace vmath_hpp::detail { template < typename A, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join( - F&& f, - const vec& a - ) { - return impl::map_join_impl( - std::forward(f), a, std::make_index_sequence{}); + auto map_join(F&& f, const vec& a) { + return impl::map_join_impl(std::forward(f), a, std::make_index_sequence{}); } template < typename A, typename B, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join( - F&& f, - const vec& a, - const vec& b - ) { - return impl::map_join_impl( - std::forward(f), a, b, std::make_index_sequence{}); + auto map_join(F&& f, const vec& a, const vec& b) { + return impl::map_join_impl(std::forward(f), a, b, std::make_index_sequence{}); } template < typename A, typename B, typename C, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join( - F&& f, - const vec& a, - const vec& b, - const vec& c - ) { - return impl::map_join_impl( - std::forward(f), a, b, c, std::make_index_sequence{}); + auto map_join(F&& f, const vec& a, const vec& b, const vec& c) { + return impl::map_join_impl(std::forward(f), a, b, c, std::make_index_sequence{}); } template < typename A, typename B, typename C, typename D, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join( - F&& f, - const vec& a, - const vec& b, - const vec& c, - const vec& d - ) { - return impl::map_join_impl( - std::forward(f), a, b, c, d, std::make_index_sequence{}); + auto map_join(F&& f, const vec& a, const vec& b, const vec& c, const vec& d) { + return impl::map_join_impl(std::forward(f), a, b, c, d, std::make_index_sequence{}); } template < typename A, typename B, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join( - F&& f, - A init, - const vec& b - ) { - return impl::fold_join_impl( - std::forward(f), std::move(init), b, std::make_index_sequence{}); + auto fold_join(F&& f, A init, const vec& b) { + return impl::fold_join_impl(std::forward(f), std::move(init), b, std::make_index_sequence{}); } template < typename A, typename B, typename C, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join( - F&& f, - A init, - const vec& b, - const vec& c - ) { - return impl::fold_join_impl( - std::forward(f), std::move(init), b, c, std::make_index_sequence{}); + auto fold_join(F&& f, A init, const vec& b, const vec& c) { + return impl::fold_join_impl(std::forward(f), std::move(init), b, c, std::make_index_sequence{}); } template < typename A, std::size_t Size, typename F > [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold1_join( - F&& f, - const vec& a - ) { - return impl::fold1_join_impl( - std::forward(f), a, std::make_index_sequence{}); + auto fold1_join(F&& f, const vec& a) { + return impl::fold1_join_impl(std::forward(f), a, std::make_index_sequence{}); } } @@ -200,7 +149,7 @@ namespace vmath_hpp template < typename T, std::size_t Size > [[nodiscard]] constexpr auto operator+(const vec& xs) { - return xs; + return map_join([](T x){ return +x; }, xs); } // -operator diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 88008e1..8cee9a0 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -16,27 +16,31 @@ TEST_CASE("vmath/vec_fun") { SUBCASE("Detail") { STATIC_CHECK(map_join([](const int& x){ return x * 2; - }, int2{1}) == int2{2}); + }, vec{1,2,3,4}) == vec{2,4,6,8}); STATIC_CHECK(map_join([](const int& x, const int& y){ return x + y; - }, int2{1}, int2{1}) == int2{2}); + }, vec{1,2,3,4}, vec{2,3,4,5}) == vec{3,5,7,9}); STATIC_CHECK(map_join([](const int& x, const int& y, const int& z){ return x + y + z; - }, int2{1}, int2{1}, int2{1}) == int2(3)); + }, vec{1,2,3,4}, vec{2,3,4,5}, vec{3,4,5,6}) == vec{6,9,12,15}); + + STATIC_CHECK(map_join([](const int& x, const int& y, const int& z, const int& w){ + return x + y + z + w; + }, vec{1,2,3,4}, vec{2,3,4,5}, vec{3,4,5,6}, vec{4,5,6,7}) == vec{10,14,18,22}); STATIC_CHECK(fold_join([](int acc, const int& x){ - return acc + x; - }, 0, int2{1}) == 2); + return acc - x; + }, 0, vec{1,2,3,4}) == -10); STATIC_CHECK(fold_join([](int acc, const int& x, const int& y){ - return acc + x + y; - }, 0, int2{1}, int2{1}) == 4); + return acc - x - y; + }, 0, vec{1,2,3,4}, vec{2,3,4,5}) == -24); STATIC_CHECK(fold1_join([](const int& acc, const int& x){ - return acc + x; - }, int2{1}) == 2); + return acc - x; + }, vec{1,2,3,4}) == -8); } SUBCASE("Operators") { From 6e3c1ba5233fbd9fefa7295231c342bd887d82d7 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 23 Feb 2021 10:24:49 +0700 Subject: [PATCH 10/15] rlength and rlength2 functions --- README.md | 18 ++++++++++++++++++ headers/vmath.hpp/vmath_ext.hpp | 2 +- headers/vmath.hpp/vmath_fun.hpp | 14 +++++++++++++- headers/vmath.hpp/vmath_qua_fun.hpp | 12 +++++++++++- headers/vmath.hpp/vmath_vec_fun.hpp | 12 +++++++++++- untests/vmath_fix_tests.cpp | 4 ++++ untests/vmath_fun_tests.cpp | 6 ++++++ untests/vmath_qua_fun_tests.cpp | 6 ++++++ untests/vmath_vec_fun_tests.cpp | 6 ++++++ 9 files changed, 76 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6c284cc..107f751 100644 --- a/README.md +++ b/README.md @@ -1302,9 +1302,15 @@ constexpr T dot(T x, T y) noexcept; template < arithmetic T > constexpr T length(T x) noexcept; +template < arithmetic T > +constexpr T rlength(T x) noexcept; + template < arithmetic T > constexpr T length2(T x) noexcept; +template < arithmetic T > +constexpr T rlength2(T x) noexcept; + template < arithmetic T > constexpr T distance(T x, T y) noexcept; @@ -1324,9 +1330,15 @@ constexpr T dot(const vec& xs, const vec& ys); template < typename T, size_t Size > T length(const vec& xs); +template < typename T, size_t Size > +T rlength(const vec& xs); + template < typename T, size_t Size > constexpr T length2(const vec& xs); +template < typename T, size_t Size > +constexpr T rlength2(const vec& xs); + template < typename T, size_t Size > T distance(const vec& xs, const vec& ys); @@ -1352,9 +1364,15 @@ constexpr T dot(const qua& xs, const qua& ys); template < typename T > T length(const qua& xs); +template < typename T > +T rlength(const qua& xs); + template < typename T > constexpr T length2(const qua& xs); +template < typename T > +constexpr T rlength2(const qua& xs); + template < typename T > T distance(const qua& xs, const qua& ys); diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index e67a9ea..47e0a37 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -877,7 +877,7 @@ namespace vmath_hpp template < typename T, std::size_t Size > [[nodiscard]] constexpr vec project(const vec& v, const vec& normal) { - return dot(v, normal) * rcp(length2(normal)) * normal; + return dot(v, normal) * rlength2(normal) * normal; } // perpendicular diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index e2ba837..d0500e1 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -317,12 +317,24 @@ namespace vmath_hpp return abs(x); } + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr rlength(T x) noexcept { + return rcp(abs(x)); + } + template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr length2(T x) noexcept { return dot(x, x); } + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr rlength2(T x) noexcept { + return rcp(dot(x, x)); + } + template < typename T > [[nodiscard]] std::enable_if_t, T> constexpr distance(T x, T y) noexcept { @@ -338,7 +350,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> normalize(T x) noexcept { - return x * rsqrt(length2(x)); + return x * rlength(x); } } diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index fac296d..e96896a 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -259,11 +259,21 @@ namespace vmath_hpp return length(vec{xs}); } + template < typename T > + [[nodiscard]] T rlength(const qua& xs) { + return rlength(vec{xs}); + } + template < typename T > [[nodiscard]] constexpr T length2(const qua& xs) { return length2(vec{xs}); } + template < typename T > + [[nodiscard]] constexpr T rlength2(const qua& xs) { + return rlength2(vec{xs}); + } + template < typename T > [[nodiscard]] T distance(const qua& xs, const qua& ys) { const qua zs = xs * conjugate(ys); @@ -377,6 +387,6 @@ namespace vmath_hpp template < typename T > [[nodiscard]] constexpr qua inverse(const qua& q) { - return conjugate(q) * rcp(length2(q)); + return conjugate(q) * rlength2(q); } } diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 951634e..8b66c28 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -778,11 +778,21 @@ namespace vmath_hpp return sqrt(dot(xs, xs)); } + template < typename T, std::size_t Size > + [[nodiscard]] T rlength(const vec& xs) { + return rsqrt(dot(xs, xs)); + } + template < typename T, std::size_t Size > [[nodiscard]] constexpr T length2(const vec& xs) { return dot(xs, xs); } + template < typename T, std::size_t Size > + [[nodiscard]] constexpr T rlength2(const vec& xs) { + return rcp(dot(xs, xs)); + } + template < typename T, std::size_t Size > [[nodiscard]] T distance(const vec& xs, const vec& ys) { return length(ys - xs); @@ -808,7 +818,7 @@ namespace vmath_hpp template < typename T, std::size_t Size > [[nodiscard]] vec normalize(const vec& xs) { - return xs * rsqrt(length2(xs)); + return xs * rlength(xs); } } diff --git a/untests/vmath_fix_tests.cpp b/untests/vmath_fix_tests.cpp index 5baa823..12f03df 100644 --- a/untests/vmath_fix_tests.cpp +++ b/untests/vmath_fix_tests.cpp @@ -256,7 +256,9 @@ namespace vmath_hpp { template fix dot(const fix2f&, const fix2f&); template fix length(const fix2f&); + template fix rlength(const fix2f&); template fix length2(const fix2f&); + template fix rlength2(const fix2f&); template fix distance(const fix2f&, const fix2f&); template fix distance2(const fix2f&, const fix2f&); template fix cross(const fix2f&, const fix2f&); @@ -268,7 +270,9 @@ namespace vmath_hpp { template fix dot(const qfix&, const qfix&); template fix length(const qfix&); + template fix rlength(const qfix&); template fix length2(const qfix&); + template fix rlength2(const qfix&); template fix distance(const qfix&, const qfix&); template qfix normalize(const qfix&); } diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index 8de5f9a..484afa7 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -107,9 +107,15 @@ TEST_CASE("vmath/fun") { STATIC_CHECK(length(10.f) == uapprox(10.f)); STATIC_CHECK(length(-10.f) == uapprox(10.f)); + STATIC_CHECK(rlength(10.f) == uapprox(0.1f)); + STATIC_CHECK(rlength(-10.f) == uapprox(0.1f)); + STATIC_CHECK(length2(10.f) == uapprox(100.f)); STATIC_CHECK(length2(-10.f) == uapprox(100.f)); + STATIC_CHECK(rlength2(10.f) == uapprox(0.01f)); + STATIC_CHECK(rlength2(-10.f) == uapprox(0.01f)); + STATIC_CHECK(distance(5.f, 10.f) == uapprox(5.f)); STATIC_CHECK(distance(-5.f, -10.f) == uapprox(5.f)); diff --git a/untests/vmath_qua_fun_tests.cpp b/untests/vmath_qua_fun_tests.cpp index 0c71cc3..80bb33e 100644 --- a/untests/vmath_qua_fun_tests.cpp +++ b/untests/vmath_qua_fun_tests.cpp @@ -136,9 +136,15 @@ TEST_CASE("vmath/qua_fun") { CHECK(length(qfloat(10.f,0.f,0.f,0.f)) == uapprox(10.f)); CHECK(length(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(10.f)); + CHECK(rlength(qfloat(10.f,0.f,0.f,0.f)) == uapprox(0.1f)); + CHECK(rlength(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(0.1f)); + STATIC_CHECK(length2(qfloat(10.f,0.f,0.f,0.f)) == uapprox(100.f)); STATIC_CHECK(length2(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(100.f)); + STATIC_CHECK(rlength2(qfloat(10.f,0.f,0.f,0.f)) == uapprox(0.01f)); + STATIC_CHECK(rlength2(qfloat(-10.f,0.f,0.f,0.f)) == uapprox(0.01f)); + CHECK(distance(qrotate_z(radians(0.f)) * 2.f, qrotate_z(radians(0.f)) * 1.5f) == uapprox(radians(0.f))); CHECK(distance(qrotate_z(radians(0.f)) * 3.f, qrotate_z(radians(360.f)) * 2.5f) == uapprox(radians(0.f))); CHECK(distance(qrotate_z(radians(0.f)) * 4.f, qrotate_z(radians(180.f)) * 3.5f) == uapprox(radians(180.f))); diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 8cee9a0..2919ed8 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -251,9 +251,15 @@ TEST_CASE("vmath/vec_fun") { CHECK(length(float2(10.f,0.f)) == uapprox(10.f)); CHECK(length(float2(-10.f,0.f)) == uapprox(10.f)); + CHECK(rlength(float2(10.f,0.f)) == uapprox(0.1f)); + CHECK(rlength(float2(-10.f,0.f)) == uapprox(0.1f)); + STATIC_CHECK(length2(float2(10.f,0.f)) == uapprox(100.f)); STATIC_CHECK(length2(float2(-10.f,0.f)) == uapprox(100.f)); + STATIC_CHECK(rlength2(float2(10.f,0.f)) == uapprox(0.01f)); + STATIC_CHECK(rlength2(float2(-10.f,0.f)) == uapprox(0.01f)); + CHECK(distance(float2(5.f,0.f), float2(10.f,0.f)) == uapprox(5.f)); CHECK(distance(float2(-5.f,0.f), float2(-10.f,0.f)) == uapprox(5.f)); From e80f49133b53446ec1a0342b57a7df94c1e1fd79 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 23 Feb 2021 22:26:40 +0700 Subject: [PATCH 11/15] return modf function --- README.md | 6 ++++ headers/vmath.hpp/vmath_fun.hpp | 6 ++++ headers/vmath.hpp/vmath_vec_fun.hpp | 14 +++++++++ untests/vmath_fix_tests.cpp | 47 +++++++++++++++-------------- untests/vmath_fun_tests.cpp | 6 ++++ untests/vmath_vec_fun_tests.cpp | 6 ++++ 6 files changed, 63 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 107f751..55ae01e 100644 --- a/README.md +++ b/README.md @@ -977,6 +977,9 @@ T fract(T x) noexcept; template < floating_point T > T fmod(T x, T y) noexcept; +template < floating_point T > +T modf(T x, T* y) noexcept; + template < floating_point T > T copysign(T x, T s) noexcept; @@ -1044,6 +1047,9 @@ vec fmod(const vec& xs, T y); template < typename T, size_t Size > vec fmod(const vec& xs, const vec& ys); +template < typename T, size_t Size > +vec modf(const vec& xs, vec* is); + template < typename T, size_t Size > vec copysign(const vec& xs, T s); diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index d0500e1..5417869 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -78,6 +78,12 @@ namespace vmath_hpp return std::fmod(x, y); } + template < typename T > + [[nodiscard]] std::enable_if_t, T> + modf(T x, T* y) noexcept { + return std::modf(x, y); + } + template < typename T > [[nodiscard]] std::enable_if_t, T> copysign(T x, T s) noexcept { diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 8b66c28..4404f37 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -505,6 +505,20 @@ namespace vmath_hpp return map_join([](T x, T y) { return fmod(x, y); }, xs, ys); } + namespace impl + { + template < typename T, std::size_t Size, std::size_t... Is > + VMATH_HPP_FORCE_INLINE + vec modf_impl(const vec& xs, vec* is, std::index_sequence) { + return { modf(xs[Is], &(*is)[Is])... }; + } + } + + template < typename T, std::size_t Size > + vec modf(const vec& xs, vec* is) { + return impl::modf_impl(xs, is, std::make_index_sequence{}); + } + template < typename T, std::size_t Size > [[nodiscard]] vec copysign(const vec& xs, T s) { return map_join([s](T x) { return copysign(x, s); }, xs); diff --git a/untests/vmath_fix_tests.cpp b/untests/vmath_fix_tests.cpp index 12f03df..0a9e21e 100644 --- a/untests/vmath_fix_tests.cpp +++ b/untests/vmath_fix_tests.cpp @@ -34,6 +34,7 @@ namespace constexpr friend fix fract(const fix& l) { using vmath_hpp::fract; return { fix{fract(l.underlying())} }; } constexpr friend fix fmod(const fix& l, const fix& r) { using vmath_hpp::fmod; return { fix{fmod(l.underlying(), r.underlying())} }; } + constexpr friend fix modf(const fix& l, fix* r) { using vmath_hpp::modf; return { fix{modf(l.underlying(), &r->underlying_)} }; } constexpr friend fix copysign(const fix& l, const fix& r) { using vmath_hpp::copysign; return { fix{copysign(l.underlying(), r.underlying())} }; } constexpr friend fix min(const fix& l, const fix& r) { using vmath_hpp::min; return fix{min(l.underlying(), r.underlying())}; } @@ -67,31 +68,31 @@ namespace constexpr friend fix radians(const fix& l) { using vmath_hpp::radians; return fix{radians(l.underlying())}; } constexpr friend fix degrees(const fix& l) { using vmath_hpp::degrees; return fix{degrees(l.underlying())}; } - friend fix sin(const fix& l) { using vmath_hpp::sin; return fix{sin(l.underlying())}; } - friend fix cos(const fix& l) { using vmath_hpp::cos; return fix{cos(l.underlying())}; } - friend fix tan(const fix& l) { using vmath_hpp::tan; return fix{tan(l.underlying())}; } - friend fix asin(const fix& l) { using vmath_hpp::asin; return fix{asin(l.underlying())}; } - friend fix acos(const fix& l) { using vmath_hpp::acos; return fix{acos(l.underlying())}; } - friend fix atan(const fix& l) { using vmath_hpp::atan; return fix{atan(l.underlying())}; } - friend fix atan2(const fix& l, const fix& r) { using vmath_hpp::atan2; return fix{atan2(l.underlying(), r.underlying())}; } - friend fix sinh(const fix& l) { using vmath_hpp::sinh; return fix{sinh(l.underlying())}; } - friend fix cosh(const fix& l) { using vmath_hpp::cosh; return fix{cosh(l.underlying())}; } - friend fix tanh(const fix& l) { using vmath_hpp::tanh; return fix{tanh(l.underlying())}; } - friend fix asinh(const fix& l) { using vmath_hpp::asinh; return fix{asinh(l.underlying())}; } - friend fix acosh(const fix& l) { using vmath_hpp::acosh; return fix{acosh(l.underlying())}; } - friend fix atanh(const fix& l) { using vmath_hpp::atanh; return fix{atanh(l.underlying())}; } - friend std::pair sincos(const fix& l) { return { sin(l), cos(l) }; } - friend void sincos(const fix& l, fix* s, fix* c) { *s = sin(l); *c = cos(l); } + constexpr friend fix sin(const fix& l) { using vmath_hpp::sin; return fix{sin(l.underlying())}; } + constexpr friend fix cos(const fix& l) { using vmath_hpp::cos; return fix{cos(l.underlying())}; } + constexpr friend fix tan(const fix& l) { using vmath_hpp::tan; return fix{tan(l.underlying())}; } + constexpr friend fix asin(const fix& l) { using vmath_hpp::asin; return fix{asin(l.underlying())}; } + constexpr friend fix acos(const fix& l) { using vmath_hpp::acos; return fix{acos(l.underlying())}; } + constexpr friend fix atan(const fix& l) { using vmath_hpp::atan; return fix{atan(l.underlying())}; } + constexpr friend fix atan2(const fix& l, const fix& r) { using vmath_hpp::atan2; return fix{atan2(l.underlying(), r.underlying())}; } + constexpr friend fix sinh(const fix& l) { using vmath_hpp::sinh; return fix{sinh(l.underlying())}; } + constexpr friend fix cosh(const fix& l) { using vmath_hpp::cosh; return fix{cosh(l.underlying())}; } + constexpr friend fix tanh(const fix& l) { using vmath_hpp::tanh; return fix{tanh(l.underlying())}; } + constexpr friend fix asinh(const fix& l) { using vmath_hpp::asinh; return fix{asinh(l.underlying())}; } + constexpr friend fix acosh(const fix& l) { using vmath_hpp::acosh; return fix{acosh(l.underlying())}; } + constexpr friend fix atanh(const fix& l) { using vmath_hpp::atanh; return fix{atanh(l.underlying())}; } + constexpr friend std::pair sincos(const fix& l) { return { sin(l), cos(l) }; } + constexpr friend void sincos(const fix& l, fix* s, fix* c) { *s = sin(l); *c = cos(l); } // - friend fix pow(const fix& l, const fix& r) { using vmath_hpp::pow; return fix{pow(l.underlying(), r.underlying())}; } - friend fix exp(const fix& l) { using vmath_hpp::exp; return fix{exp(l.underlying())}; } - friend fix log(const fix& l) { using vmath_hpp::log; return fix{log(l.underlying())}; } - friend fix exp2(const fix& l) { using vmath_hpp::exp2; return fix{exp2(l.underlying())}; } - friend fix log2(const fix& l) { using vmath_hpp::log2; return fix{log2(l.underlying())}; } - friend fix sqrt(const fix& l) { using vmath_hpp::sqrt; return fix{sqrt(l.underlying())}; } - friend fix rsqrt(const fix& l) { using vmath_hpp::rsqrt; return fix{rsqrt(l.underlying())}; } + constexpr friend fix pow(const fix& l, const fix& r) { using vmath_hpp::pow; return fix{pow(l.underlying(), r.underlying())}; } + constexpr friend fix exp(const fix& l) { using vmath_hpp::exp; return fix{exp(l.underlying())}; } + constexpr friend fix log(const fix& l) { using vmath_hpp::log; return fix{log(l.underlying())}; } + constexpr friend fix exp2(const fix& l) { using vmath_hpp::exp2; return fix{exp2(l.underlying())}; } + constexpr friend fix log2(const fix& l) { using vmath_hpp::log2; return fix{log2(l.underlying())}; } + constexpr friend fix sqrt(const fix& l) { using vmath_hpp::sqrt; return fix{sqrt(l.underlying())}; } + constexpr friend fix rsqrt(const fix& l) { using vmath_hpp::rsqrt; return fix{rsqrt(l.underlying())}; } // @@ -169,6 +170,8 @@ namespace vmath_hpp template fix2f fmod(const fix2f&, fix); template fix2f fmod(const fix2f&, const fix2f&); + template fix2f modf(const fix2f&, fix2f*); + template fix2f copysign(const fix2f&, fix); template fix2f copysign(const fix2f&, const fix2f&); diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index 484afa7..a681dc0 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -77,6 +77,12 @@ TEST_CASE("vmath/fun") { CHECK(fmod(1.7f, 1.2f) == uapprox(0.5f)); + { + float out_i{}; + CHECK(modf(1.7f, &out_i) == uapprox(0.7f)); + CHECK(out_i == uapprox(1.f)); + } + STATIC_CHECK(min(0.f, 1.f) == uapprox(0.f)); STATIC_CHECK(max(0.f, 1.f) == uapprox(1.f)); diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 2919ed8..ea893fe 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -205,6 +205,12 @@ TEST_CASE("vmath/vec_fun") { CHECK(fmod(float2(1.7f), 1.2f) == uapprox2(0.5f)); CHECK(fmod(float2(1.7f), float2(1.2f)) == uapprox2(0.5f)); + { + float2 out_i{}; + CHECK(modf(float2(1.7f), &out_i) == uapprox2(0.7f)); + CHECK(out_i.x == uapprox(1.f)); + } + STATIC_CHECK(min(int2(1,2)) == 1); STATIC_CHECK(min(int2(1,2), 1) == int2(1,1)); STATIC_CHECK(min(1, int2(1,2)) == int2(1,1)); From e95b9cf8987936eb40d93b39dd852d70570385e7 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 24 Feb 2021 03:40:22 +0700 Subject: [PATCH 12/15] return faceforward, reflect and refract functions --- .github/workflows/windows.yml | 2 +- README.md | 18 ++++++++++++++++++ headers/vmath.hpp/vmath_fun.hpp | 20 ++++++++++++++++++++ headers/vmath.hpp/vmath_vec_fun.hpp | 17 +++++++++++++++++ untests/vmath_fix_tests.cpp | 3 +++ untests/vmath_fun_tests.cpp | 4 ++++ untests/vmath_vec_fun_tests.cpp | 4 ++++ 7 files changed, 67 insertions(+), 1 deletion(-) diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 86957a4..1c48908 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -14,7 +14,7 @@ jobs: - { os: "windows-2016", vs: "Visual Studio 2017", arch: "x64" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x86" } - { os: "windows-2019", vs: "Visual Studio 2019", arch: "x64" } - name: "${{matrix.config.vs}}" + name: "${{matrix.config.vs}} ${{matrix.config.arch}}" steps: - uses: actions/checkout@v2 - name: Build && Test diff --git a/README.md b/README.md index 55ae01e..9cf8abb 100644 --- a/README.md +++ b/README.md @@ -1325,6 +1325,15 @@ constexpr T distance2(T x, T y) noexcept; template < floating_point T > T normalize(T x) noexcept; + +template < floating_point T > +constexpr T faceforward(T n, T i, T nref) noexcept; + +template < floating_point T > +constexpr T reflect(T i, T n) noexcept; + +template < floating_point T > +T refract(T i, T n, T eta) noexcept; ``` #### Vector @@ -1359,6 +1368,15 @@ constexpr vec cross(const vec& xs, const vec& ys); template < typename T, size_t Size > vec normalize(const vec& xs); + +template < typename T, size_t Size > +constexpr vec faceforward(const vec& n, const vec& i, const vec& nref); + +template < typename T, size_t Size > +constexpr vec reflect(const vec& i, const vec& n); + +template < typename T, size_t Size > +vec refract(const vec& i, const vec& n, T eta); ``` #### Quaternion diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index 5417869..e753dd9 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -358,6 +358,26 @@ namespace vmath_hpp normalize(T x) noexcept { return x * rlength(x); } + + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr faceforward(T n, T i, T nref) noexcept { + return dot(nref, i) < T{0} ? n : -n; + } + + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr reflect(T i, T n) noexcept { + return i - T{2} * dot(n, i) * n; + } + + template < typename T > + [[nodiscard]] std::enable_if_t, T> + refract(T i, T n, T eta) noexcept { + const T d = dot(n, i); + const T k = T{1} - sqr(eta) * (T{1} - sqr(d)); + return k < T{0} ? T{0} : (eta * i - (eta * d + sqrt(k)) * n); + } } // diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 4404f37..4a4647b 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -834,6 +834,23 @@ namespace vmath_hpp [[nodiscard]] vec normalize(const vec& xs) { return xs * rlength(xs); } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec faceforward(const vec& n, const vec& i, const vec& nref) { + return dot(nref, i) < T{0} ? n : -n; + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec reflect(const vec& i, const vec& n) { + return i - T{2} * dot(n, i) * n; + } + + template < typename T, std::size_t Size > + [[nodiscard]] vec refract(const vec& i, const vec& n, T eta) { + const T d = dot(n, i); + const T k = T{1} - sqr(eta) * (T{1} - sqr(d)); + return k < T{0} ? vec{T{0}} : (eta * i - (eta * d + sqrt(k)) * n); + } } // diff --git a/untests/vmath_fix_tests.cpp b/untests/vmath_fix_tests.cpp index 0a9e21e..1d0d4ad 100644 --- a/untests/vmath_fix_tests.cpp +++ b/untests/vmath_fix_tests.cpp @@ -267,6 +267,9 @@ namespace vmath_hpp template fix cross(const fix2f&, const fix2f&); template fix3f cross(const fix3f&, const fix3f&); template fix2f normalize(const fix2f&); + template fix3f faceforward(const fix3f&, const fix3f&, const fix3f&); + template fix3f reflect(const fix3f&, const fix3f&); + template fix3f refract(const fix3f&, const fix3f&, fix); } namespace vmath_hpp diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index a681dc0..c2e5bf7 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -130,6 +130,10 @@ TEST_CASE("vmath/fun") { STATIC_CHECK(dot(2.f, 5.f) == uapprox(10.f)); CHECK(normalize(0.5f) == uapprox(1.f)); + + STATIC_CHECK(faceforward(1.f, 2.f, 3.f) == uapprox(-1.f)); + STATIC_CHECK(reflect(1.f, 2.f) == uapprox(-7.f)); + CHECK(refract(1.f, 2.f, 1.f) == uapprox(-7.f)); } SUBCASE("Relational Functions") { diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index ea893fe..31b4915 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -276,6 +276,10 @@ TEST_CASE("vmath/vec_fun") { STATIC_CHECK(cross(int2(1,0),int2(0,1)) == 1); STATIC_CHECK(cross(int3(1,0,0),int3(0,1,0)) == int3(0,0,1)); CHECK(normalize(float2(0.5f,0.f)).x == uapprox(1.f)); + + STATIC_CHECK(faceforward(float2(1.f), float2(2.f), float2(3.f)).x == uapprox(-1.f)); + STATIC_CHECK(reflect(float2(1.f), float2(2.f)).x == uapprox(-15.f)); + CHECK(refract(float2(1.f), float2(2.f), 1.f).x == uapprox(-15.f)); } SUBCASE("Relational Functions") { From 7c0427ce761e4d60f2eee2a78f8617564891b9a8 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 24 Feb 2021 04:41:23 +0700 Subject: [PATCH 13/15] mark constexpr all generic functions --- headers/vmath.hpp/vmath_ext.hpp | 90 ++++++++++++++--------------- headers/vmath.hpp/vmath_fun.hpp | 2 +- headers/vmath.hpp/vmath_mat.hpp | 2 +- headers/vmath.hpp/vmath_qua.hpp | 2 +- headers/vmath.hpp/vmath_qua_fun.hpp | 16 ++--- headers/vmath.hpp/vmath_vec.hpp | 2 +- headers/vmath.hpp/vmath_vec_fun.hpp | 78 ++++++++++++------------- untests/vmath_fun_tests.cpp | 2 +- 8 files changed, 97 insertions(+), 97 deletions(-) diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index 47e0a37..6762382 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -294,7 +294,7 @@ namespace vmath_hpp // rotate template < typename T > - [[nodiscard]] mat rotate(const qua& q) { + [[nodiscard]] constexpr mat rotate(const qua& q) { /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/ @@ -324,12 +324,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat rotate(const mat& m, const qua& q) { + [[nodiscard]] constexpr mat rotate(const mat& m, const qua& q) { return m * rotate(q); } template < typename T > - [[nodiscard]] mat rotate(T angle, const vec& axis) { + [[nodiscard]] constexpr mat rotate(T angle, const vec& axis) { /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToMatrix/ @@ -362,12 +362,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat rotate(const mat& m, T angle, const vec& axis) { + [[nodiscard]] constexpr mat rotate(const mat& m, T angle, const vec& axis) { return m * rotate(angle, axis); } template < typename T > - [[nodiscard]] mat rotate_x(T angle) { + [[nodiscard]] constexpr mat rotate_x(T angle) { /// REFERENCE: /// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/ @@ -381,12 +381,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat rotate_x(const mat& m, T angle) { + [[nodiscard]] constexpr mat rotate_x(const mat& m, T angle) { return m * rotate_x(angle); } template < typename T > - [[nodiscard]] mat rotate_y(T angle) { + [[nodiscard]] constexpr mat rotate_y(T angle) { /// REFERENCE: /// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/ @@ -400,12 +400,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat rotate_y(const mat& m, T angle) { + [[nodiscard]] constexpr mat rotate_y(const mat& m, T angle) { return m * rotate_y(angle); } template < typename T > - [[nodiscard]] mat rotate_z(T angle) { + [[nodiscard]] constexpr mat rotate_z(T angle) { /// REFERENCE: /// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/ @@ -419,7 +419,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat rotate_z(const mat& m, T angle) { + [[nodiscard]] constexpr mat rotate_z(const mat& m, T angle) { return m * rotate_z(angle); } @@ -455,7 +455,7 @@ namespace vmath_hpp // look_at template < typename T > - [[nodiscard]] mat look_at_lh(const vec& eye, const vec& at, const vec& up) { + [[nodiscard]] constexpr mat look_at_lh(const vec& eye, const vec& at, const vec& up) { /// REFERENCE: /// https://www.euclideanspace.com/maths/algebra/vectors/lookat/ @@ -475,7 +475,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat look_at_rh(const vec& eye, const vec& at, const vec& up) { + [[nodiscard]] constexpr mat look_at_rh(const vec& eye, const vec& at, const vec& up) { /// REFERENCE: /// https://www.euclideanspace.com/maths/algebra/vectors/lookat/ @@ -532,7 +532,7 @@ namespace vmath_hpp // rotate template < typename T > - [[nodiscard]] mat rotate(T angle) { + [[nodiscard]] constexpr mat rotate(T angle) { /// REFERENCE: /// http://www.euclideanspace.com/maths/algebra/matrix/orthogonal/rotation/ @@ -545,7 +545,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat rotate(const mat& m, T angle) { + [[nodiscard]] constexpr mat rotate(const mat& m, T angle) { return m * rotate(angle); } @@ -647,7 +647,7 @@ namespace vmath_hpp // orthographic template < typename T > - [[nodiscard]] mat orthographic_lh(T width, T height, T znear, T zfar) { + [[nodiscard]] constexpr mat orthographic_lh(T width, T height, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixortholh @@ -668,7 +668,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat orthographic_rh(T width, T height, T znear, T zfar) { + [[nodiscard]] constexpr mat orthographic_rh(T width, T height, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixorthorh @@ -689,7 +689,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat orthographic_lh(T left, T right, T bottom, T top, T znear, T zfar) { + [[nodiscard]] constexpr mat orthographic_lh(T left, T right, T bottom, T top, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixorthooffcenterlh @@ -705,7 +705,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat orthographic_rh(T left, T right, T bottom, T top, T znear, T zfar) { + [[nodiscard]] constexpr mat orthographic_rh(T left, T right, T bottom, T top, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixorthooffcenterrh @@ -723,7 +723,7 @@ namespace vmath_hpp // perspective template < typename T > - [[nodiscard]] mat perspective_lh(T width, T height, T znear, T zfar) { + [[nodiscard]] constexpr mat perspective_lh(T width, T height, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivelh @@ -740,7 +740,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat perspective_rh(T width, T height, T znear, T zfar) { + [[nodiscard]] constexpr mat perspective_rh(T width, T height, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiverh @@ -757,7 +757,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat perspective_lh(T left, T right, T bottom, T top, T znear, T zfar) { + [[nodiscard]] constexpr mat perspective_lh(T left, T right, T bottom, T top, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiveoffcenterlh @@ -774,7 +774,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat perspective_rh(T left, T right, T bottom, T top, T znear, T zfar) { + [[nodiscard]] constexpr mat perspective_rh(T left, T right, T bottom, T top, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectiveoffcenterrh @@ -791,7 +791,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat perspective_fov_lh(T fovy, T aspect, T znear, T zfar) { + [[nodiscard]] constexpr mat perspective_fov_lh(T fovy, T aspect, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovlh @@ -808,7 +808,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] mat perspective_fov_rh(T fovy, T aspect, T znear, T zfar) { + [[nodiscard]] constexpr mat perspective_fov_rh(T fovy, T aspect, T znear, T zfar) { /// REFERENCE: /// https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh @@ -833,7 +833,7 @@ namespace vmath_hpp // angle template < typename T, std::size_t Size > - [[nodiscard]] T angle(const vec& x, const vec& y) { + [[nodiscard]] constexpr T angle(const vec& x, const vec& y) { const T rs = rsqrt(length2(x) * length2(y)); return acos(clamp(dot(x, y) * rs, -T{1}, T{1})); } @@ -841,7 +841,7 @@ namespace vmath_hpp // rotate template < typename T > - [[nodiscard]] vec rotate(const vec& v, T angle) { + [[nodiscard]] constexpr vec rotate(const vec& v, T angle) { const auto [s, c] = sincos(angle); return { v.x * c - v.y * s, @@ -849,27 +849,27 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] vec rotate_x(const vec& v, T angle) { + [[nodiscard]] constexpr vec rotate_x(const vec& v, T angle) { return v * qrotate(angle, unit3_x); } template < typename T > - [[nodiscard]] vec rotate_y(const vec& v, T angle) { + [[nodiscard]] constexpr vec rotate_y(const vec& v, T angle) { return v * qrotate(angle, unit3_y); } template < typename T > - [[nodiscard]] vec rotate_z(const vec& v, T angle) { + [[nodiscard]] constexpr vec rotate_z(const vec& v, T angle) { return v * qrotate(angle, unit3_z); } template < typename T > - [[nodiscard]] vec rotate(const vec& v, const qua& q) { + [[nodiscard]] constexpr vec rotate(const vec& v, const qua& q) { return v * q; } template < typename T > - [[nodiscard]] vec rotate(const vec& v, T angle, const vec& axis) { + [[nodiscard]] constexpr vec rotate(const vec& v, T angle, const vec& axis) { return v * qrotate(angle, axis); } @@ -897,7 +897,7 @@ namespace vmath_hpp // qrotate template < typename T > - [[nodiscard]] qua qrotate(const mat& m) { + [[nodiscard]] constexpr qua qrotate(const mat& m) { /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ @@ -915,12 +915,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] qua qrotate(const qua& q, const mat& m) { + [[nodiscard]] constexpr qua qrotate(const qua& q, const mat& m) { return q * qrotate(m); } template < typename T > - [[nodiscard]] qua qrotate(const vec& from, const vec& to) { + [[nodiscard]] constexpr qua qrotate(const vec& from, const vec& to) { /// REFERENCE: /// http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final @@ -937,12 +937,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] qua qrotate(const qua& q, const vec& from, const vec& to) { + [[nodiscard]] constexpr qua qrotate(const qua& q, const vec& from, const vec& to) { return q * qrotate(from, to); } template < typename T > - [[nodiscard]] qua qrotate(T angle, const vec& axis) { + [[nodiscard]] constexpr qua qrotate(T angle, const vec& axis) { /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ @@ -953,12 +953,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] qua qrotate(const qua& q, T angle, const vec& axis) { + [[nodiscard]] constexpr qua qrotate(const qua& q, T angle, const vec& axis) { return q * qrotate(angle, axis); } template < typename T > - [[nodiscard]] qua qrotate_x(T angle) { + [[nodiscard]] constexpr qua qrotate_x(T angle) { /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ @@ -968,12 +968,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] qua qrotate_x(const qua& q, T angle) { + [[nodiscard]] constexpr qua qrotate_x(const qua& q, T angle) { return qrotate(q, angle, unit3_x); } template < typename T > - [[nodiscard]] qua qrotate_y(T angle) { + [[nodiscard]] constexpr qua qrotate_y(T angle) { /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ @@ -983,12 +983,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] qua qrotate_y(const qua& q, T angle) { + [[nodiscard]] constexpr qua qrotate_y(const qua& q, T angle) { return qrotate(q, angle, unit3_y); } template < typename T > - [[nodiscard]] qua qrotate_z(T angle) { + [[nodiscard]] constexpr qua qrotate_z(T angle) { /// REFERENCE: /// http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ @@ -998,14 +998,14 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] qua qrotate_z(const qua& q, T angle) { + [[nodiscard]] constexpr qua qrotate_z(const qua& q, T angle) { return qrotate(q, angle, unit3_z); } // look_at template < typename T > - [[nodiscard]] qua qlook_at_lh(const vec& dir, const vec& up) { + [[nodiscard]] constexpr qua qlook_at_lh(const vec& dir, const vec& up) { /// REFERENCE: /// https://www.euclideanspace.com/maths/algebra/vectors/lookat/ @@ -1020,7 +1020,7 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] qua qlook_at_rh(const vec& dir, const vec& up) { + [[nodiscard]] constexpr qua qlook_at_rh(const vec& dir, const vec& up) { /// REFERENCE: /// https://www.euclideanspace.com/maths/algebra/vectors/lookat/ diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index e753dd9..e87e262 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -355,7 +355,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> - normalize(T x) noexcept { + constexpr normalize(T x) noexcept { return x * rlength(x); } diff --git a/headers/vmath.hpp/vmath_mat.hpp b/headers/vmath.hpp/vmath_mat.hpp index 182531e..42bbba8 100644 --- a/headers/vmath.hpp/vmath_mat.hpp +++ b/headers/vmath.hpp/vmath_mat.hpp @@ -218,7 +218,7 @@ namespace vmath_hpp using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - static constexpr std::size_t size = Size; + static inline constexpr std::size_t size = Size; public: using base_type::mat_base; using base_type::rows; diff --git a/headers/vmath.hpp/vmath_qua.hpp b/headers/vmath.hpp/vmath_qua.hpp index dc66ed8..fedac84 100644 --- a/headers/vmath.hpp/vmath_qua.hpp +++ b/headers/vmath.hpp/vmath_qua.hpp @@ -79,7 +79,7 @@ namespace vmath_hpp using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - static constexpr std::size_t size = 4; + static inline constexpr std::size_t size = 4; public: using base_type::qua_base; using base_type::operator[]; diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index e96896a..efb03ea 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -203,24 +203,24 @@ namespace vmath_hpp namespace vmath_hpp { template < typename T > - [[nodiscard]] qua lerp(const qua& xs, const qua& ys, T a) { + [[nodiscard]] constexpr qua lerp(const qua& xs, const qua& ys, T a) { return qua(lerp(vec{xs}, vec{ys}, a)); } template < typename T > - [[nodiscard]] qua lerp(const qua& xs, const qua& ys, T x_a, T y_a) { + [[nodiscard]] constexpr qua lerp(const qua& xs, const qua& ys, T x_a, T y_a) { return qua(lerp(vec{xs}, vec{ys}, x_a, y_a)); } template < typename T > - [[nodiscard]] qua nlerp(const qua& unit_xs, const qua& unit_ys, T a) { + [[nodiscard]] constexpr qua nlerp(const qua& unit_xs, const qua& unit_ys, T a) { const T xs_scale = T{1} - a; const T ys_scale = a * sign(dot(unit_xs, unit_ys)); return normalize(lerp(unit_xs, unit_ys, xs_scale, ys_scale)); } template < typename T > - [[nodiscard]] qua slerp(const qua& unit_xs, const qua& unit_ys, T a) { + [[nodiscard]] constexpr qua slerp(const qua& unit_xs, const qua& unit_ys, T a) { /// REFERENCE: /// http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/ @@ -255,12 +255,12 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] T length(const qua& xs) { + [[nodiscard]] constexpr T length(const qua& xs) { return length(vec{xs}); } template < typename T > - [[nodiscard]] T rlength(const qua& xs) { + [[nodiscard]] constexpr T rlength(const qua& xs) { return rlength(vec{xs}); } @@ -275,13 +275,13 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] T distance(const qua& xs, const qua& ys) { + [[nodiscard]] constexpr T distance(const qua& xs, const qua& ys) { const qua zs = xs * conjugate(ys); return T{2} * atan2(length(zs.v), abs(zs.s)); } template < typename T > - [[nodiscard]] qua normalize(const qua& xs) { + [[nodiscard]] constexpr qua normalize(const qua& xs) { return qua(normalize(vec{xs})); } } diff --git a/headers/vmath.hpp/vmath_vec.hpp b/headers/vmath.hpp/vmath_vec.hpp index 896b6f9..2aaa027 100644 --- a/headers/vmath.hpp/vmath_vec.hpp +++ b/headers/vmath.hpp/vmath_vec.hpp @@ -172,7 +172,7 @@ namespace vmath_hpp using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - static constexpr std::size_t size = Size; + static inline constexpr std::size_t size = Size; public: using base_type::vec_base; using base_type::operator[]; diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 4a4647b..9cf110e 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -471,61 +471,61 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] vec floor(const vec& xs) { + [[nodiscard]] constexpr vec floor(const vec& xs) { return map_join([](T x) { return floor(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec trunc(const vec& xs) { + [[nodiscard]] constexpr vec trunc(const vec& xs) { return map_join([](T x) { return trunc(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec round(const vec& xs) { + [[nodiscard]] constexpr vec round(const vec& xs) { return map_join([](T x) { return round(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec ceil(const vec& xs) { + [[nodiscard]] constexpr vec ceil(const vec& xs) { return map_join([](T x) { return ceil(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec fract(const vec& xs) { + [[nodiscard]] constexpr vec fract(const vec& xs) { return map_join([](T x) { return fract(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec fmod(const vec& xs, T y) { + [[nodiscard]] constexpr vec fmod(const vec& xs, T y) { return map_join([y](T x) { return fmod(x, y); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec fmod(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec fmod(const vec& xs, const vec& ys) { return map_join([](T x, T y) { return fmod(x, y); }, xs, ys); } namespace impl { template < typename T, std::size_t Size, std::size_t... Is > - VMATH_HPP_FORCE_INLINE + constexpr VMATH_HPP_FORCE_INLINE vec modf_impl(const vec& xs, vec* is, std::index_sequence) { return { modf(xs[Is], &(*is)[Is])... }; } } template < typename T, std::size_t Size > - vec modf(const vec& xs, vec* is) { + constexpr vec modf(const vec& xs, vec* is) { return impl::modf_impl(xs, is, std::make_index_sequence{}); } template < typename T, std::size_t Size > - [[nodiscard]] vec copysign(const vec& xs, T s) { + [[nodiscard]] constexpr vec copysign(const vec& xs, T s) { return map_join([s](T x) { return copysign(x, s); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec copysign(const vec& xs, const vec& ss) { + [[nodiscard]] constexpr vec copysign(const vec& xs, const vec& ss) { return map_join([](T x, T s) { return copysign(x, s); }, xs, ss); } @@ -634,7 +634,7 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] vec fma(const vec& as, const vec& bs, const vec& cs) { + [[nodiscard]] constexpr vec fma(const vec& as, const vec& bs, const vec& cs) { return map_join([](T a, T b, T c) { return fma(a, b, c); }, as, bs, cs); } } @@ -656,77 +656,77 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] vec sin(const vec& xs) { + [[nodiscard]] constexpr vec sin(const vec& xs) { return map_join([](T x) { return sin(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec cos(const vec& xs) { + [[nodiscard]] constexpr vec cos(const vec& xs) { return map_join([](T x) { return cos(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec tan(const vec& xs) { + [[nodiscard]] constexpr vec tan(const vec& xs) { return map_join([](T x) { return tan(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec asin(const vec& xs) { + [[nodiscard]] constexpr vec asin(const vec& xs) { return map_join([](T x) { return asin(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec acos(const vec& xs) { + [[nodiscard]] constexpr vec acos(const vec& xs) { return map_join([](T x) { return acos(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec atan(const vec& xs) { + [[nodiscard]] constexpr vec atan(const vec& xs) { return map_join([](T x) { return atan(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec atan2(const vec& ys, const vec& xs) { + [[nodiscard]] constexpr vec atan2(const vec& ys, const vec& xs) { return map_join([](T y, T x) { return atan2(y, x); }, ys, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec sinh(const vec& xs) { + [[nodiscard]] constexpr vec sinh(const vec& xs) { return map_join([](T x) { return sinh(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec cosh(const vec& xs) { + [[nodiscard]] constexpr vec cosh(const vec& xs) { return map_join([](T x) { return cosh(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec tanh(const vec& xs) { + [[nodiscard]] constexpr vec tanh(const vec& xs) { return map_join([](T x) { return tanh(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec asinh(const vec& xs) { + [[nodiscard]] constexpr vec asinh(const vec& xs) { return map_join([](T x) { return asinh(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec acosh(const vec& xs) { + [[nodiscard]] constexpr vec acosh(const vec& xs) { return map_join([](T x) { return acosh(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec atanh(const vec& xs) { + [[nodiscard]] constexpr vec atanh(const vec& xs) { return map_join([](T x) { return atanh(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] std::pair, vec> sincos(const vec& xs) { + [[nodiscard]] constexpr std::pair, vec> sincos(const vec& xs) { return { sin(xs), cos(xs) }; } template < typename T, std::size_t Size > - void sincos(const vec& xs, vec* ss, vec* cs) { + constexpr void sincos(const vec& xs, vec* ss, vec* cs) { *ss = sin(xs); *cs = cos(xs); } @@ -739,37 +739,37 @@ namespace vmath_hpp namespace vmath_hpp { template < typename T, std::size_t Size > - [[nodiscard]] vec pow(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec pow(const vec& xs, const vec& ys) { return map_join([](T x, T y) { return pow(x, y); }, xs, ys); } template < typename T, std::size_t Size > - [[nodiscard]] vec exp(const vec& xs) { + [[nodiscard]] constexpr vec exp(const vec& xs) { return map_join([](T x) { return exp(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec log(const vec& xs) { + [[nodiscard]] constexpr vec log(const vec& xs) { return map_join([](T x) { return log(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec exp2(const vec& xs) { + [[nodiscard]] constexpr vec exp2(const vec& xs) { return map_join([](T x) { return exp2(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec log2(const vec& xs) { + [[nodiscard]] constexpr vec log2(const vec& xs) { return map_join([](T x) { return log2(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec sqrt(const vec& xs) { + [[nodiscard]] constexpr vec sqrt(const vec& xs) { return map_join([](T x) { return sqrt(x); }, xs); } template < typename T, std::size_t Size > - [[nodiscard]] vec rsqrt(const vec& xs) { + [[nodiscard]] constexpr vec rsqrt(const vec& xs) { return map_join([](T x) { return rsqrt(x); }, xs); } } @@ -788,12 +788,12 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] T length(const vec& xs) { + [[nodiscard]] constexpr T length(const vec& xs) { return sqrt(dot(xs, xs)); } template < typename T, std::size_t Size > - [[nodiscard]] T rlength(const vec& xs) { + [[nodiscard]] constexpr T rlength(const vec& xs) { return rsqrt(dot(xs, xs)); } @@ -808,7 +808,7 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] T distance(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr T distance(const vec& xs, const vec& ys) { return length(ys - xs); } @@ -831,7 +831,7 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] vec normalize(const vec& xs) { + [[nodiscard]] constexpr vec normalize(const vec& xs) { return xs * rlength(xs); } @@ -846,7 +846,7 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] vec refract(const vec& i, const vec& n, T eta) { + [[nodiscard]] constexpr vec refract(const vec& i, const vec& n, T eta) { const T d = dot(n, i); const T k = T{1} - sqr(eta) * (T{1} - sqr(d)); return k < T{0} ? vec{T{0}} : (eta * i - (eta * d + sqrt(k)) * n); diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index c2e5bf7..4817f09 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -129,7 +129,7 @@ TEST_CASE("vmath/fun") { STATIC_CHECK(distance2(-5.f, -10.f) == uapprox(25.f)); STATIC_CHECK(dot(2.f, 5.f) == uapprox(10.f)); - CHECK(normalize(0.5f) == uapprox(1.f)); + STATIC_CHECK(normalize(0.5f) == uapprox(1.f)); STATIC_CHECK(faceforward(1.f, 2.f, 3.f) == uapprox(-1.f)); STATIC_CHECK(reflect(1.f, 2.f) == uapprox(-7.f)); From 1107d936a8b3d2df1c30ae34889a0b54666af7ac Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 24 Feb 2021 04:45:56 +0700 Subject: [PATCH 14/15] remove all constexpr and noexcept specs from readme --- README.md | 1036 ++++++++++++++++++++++++++--------------------------- 1 file changed, 518 insertions(+), 518 deletions(-) diff --git a/README.md b/README.md index 9cf8abb..6103240 100644 --- a/README.md +++ b/README.md @@ -88,9 +88,9 @@ public: T x = T{0}; T y = T{0}; - constexpr vec_base() = default; - constexpr explicit vec_base(T v); - constexpr vec_base(T x, T y); + vec_base() = default; + explicit vec_base(T v); + vec_base(T x, T y); }; template < typename T > @@ -100,13 +100,13 @@ public: T y = T{0}; T z = T{0}; - constexpr vec_base() = default; - constexpr explicit vec_base(T v); - constexpr vec_base(T x, T y, T z); - constexpr vec_base(const vec_base& xy, T z); - constexpr vec_base(T x, const vec_base& yz); + vec_base() = default; + explicit vec_base(T v); + vec_base(T x, T y, T z); + vec_base(const vec_base& xy, T z); + vec_base(T x, const vec_base& yz); - constexpr explicit operator vec() const; + explicit operator vec() const; }; template < typename T > @@ -117,18 +117,18 @@ public: T z = T{0}; T w = T{0}; - constexpr vec_base() = default; - constexpr explicit vec_base(T v); - constexpr vec_base(T x, T y, T z, T w); - constexpr vec_base(const vec_base& xy, T z, T w); - constexpr vec_base(T x, const vec_base& yz, T w); - constexpr vec_base(T x, T y, const vec_base& zw); - constexpr vec_base(const vec_base& xy, const vec_base& zw); - constexpr vec_base(const vec_base& xyz, T w); - constexpr vec_base(T x, const vec_base& yzw); + vec_base() = default; + explicit vec_base(T v); + vec_base(T x, T y, T z, T w); + vec_base(const vec_base& xy, T z, T w); + vec_base(T x, const vec_base& yz, T w); + vec_base(T x, T y, const vec_base& zw); + vec_base(const vec_base& xy, const vec_base& zw); + vec_base(const vec_base& xyz, T w); + vec_base(T x, const vec_base& yzw); - constexpr explicit operator vec() const; - constexpr explicit operator vec() const; + explicit operator vec() const; + explicit operator vec() const; }; template < typename T, size_t Size > @@ -149,37 +149,37 @@ public: using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - static constexpr size_t size = Size; + static inline size_t size = Size; - constexpr vec() = default; - constexpr vec(const vec&) = default; - constexpr vec& operator=(const vec&) = default; + vec() = default; + vec(const vec&) = default; + vec& operator=(const vec&) = default; - void swap(vec& other) noexcept(is_nothrow_swappable_v); + void swap(vec& other); - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const; + reverse_iterator rend(); + const_reverse_iterator rend() const; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + const_iterator cbegin() const; + const_iterator cend() const; + const_reverse_iterator crbegin() const; + const_reverse_iterator crend() const; - pointer data() noexcept; - const_pointer data() const noexcept; + pointer data(); + const_pointer data() const; - constexpr reference at(size_t index); - constexpr const_reference at(size_t index) const; + reference at(size_t index); + const_reference at(size_t index) const; - constexpr reference operator[](size_t index) noexcept; - constexpr const_reference operator[](size_t index) const noexcept; + reference operator[](size_t index); + const_reference operator[](size_t index) const; }; using bool2 = vec; @@ -226,15 +226,15 @@ public: row_type{T{1}, T{0}}, row_type{T{0}, T{1}}}; - constexpr mat_base() = default; - constexpr explicit mat_base(T d); - constexpr explicit mat_base(const row_type& d); + mat_base() = default; + explicit mat_base(T d); + explicit mat_base(const row_type& d); - constexpr mat_base( + mat_base( T m11, T m12, T m21, T m22); - constexpr mat_base( + mat_base( const row_type& row0, const row_type& row1); }; @@ -249,27 +249,27 @@ public: row_type{T{0}, T{1}, T{0}}, row_type{T{0}, T{0}, T{1}}}; - constexpr mat_base() = default; - constexpr explicit mat_base(T d); - constexpr explicit mat_base(const row_type& d); + mat_base() = default; + explicit mat_base(T d); + explicit mat_base(const row_type& d); - constexpr mat_base( + mat_base( T m11, T m12, T m13, T m21, T m22, T m23, T m31, T m32, T m33); - constexpr mat_base( + mat_base( const row_type& row0, const row_type& row1, const row_type& row2); - constexpr mat_base( + mat_base( const mat_base& m, const vec_base& v); - constexpr explicit mat_base(const mat_base& other); + explicit mat_base(const mat_base& other); - constexpr explicit operator mat() const; + explicit operator mat() const; }; template < typename T > @@ -283,31 +283,31 @@ public: row_type{T{0}, T{0}, T{1}, T{0}}, row_type{T{0}, T{0}, T{0}, T{1}}}; - constexpr mat_base() = default; - constexpr explicit mat_base(T d); - constexpr explicit mat_base(const row_type& d); + mat_base() = default; + explicit mat_base(T d); + explicit mat_base(const row_type& d); - constexpr mat_base( + mat_base( T m11, T m12, T m13, T m14, T m21, T m22, T m23, T m24, T m31, T m32, T m33, T m34, T m41, T m42, T m43, T m44); - constexpr mat_base( + mat_base( const row_type& row0, const row_type& row1, const row_type& row2, const row_type& row3); - constexpr mat_base( + mat_base( const mat_base& m, const vec_base& v); - constexpr explicit mat_base(const mat_base& other); - constexpr explicit mat_base(const mat_base& other); + explicit mat_base(const mat_base& other); + explicit mat_base(const mat_base& other); - constexpr explicit operator mat() const; - constexpr explicit operator mat() const; + explicit operator mat() const; + explicit operator mat() const; }; template < typename T, size_t Size > @@ -330,37 +330,37 @@ public: using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - static constexpr size_t size = Size; + static inline size_t size = Size; - constexpr mat() = default; - constexpr mat(const mat&) = default; - constexpr mat& operator=(const mat&) = default; + mat() = default; + mat(const mat&) = default; + mat& operator=(const mat&) = default; - void swap(mat& other) noexcept(is_nothrow_swappable_v); + void swap(mat& other); - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const; + reverse_iterator rend(); + const_reverse_iterator rend() const; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + const_iterator cbegin() const; + const_iterator cend() const; + const_reverse_iterator crbegin() const; + const_reverse_iterator crend() const; - pointer data() noexcept; - const_pointer data() const noexcept; + pointer data(); + const_pointer data() const; - constexpr reference at(size_t index); - constexpr const_reference at(size_t index) const; + reference at(size_t index); + const_reference at(size_t index) const; - constexpr reference operator[](size_t index) noexcept; - constexpr const_reference operator[](size_t index) const noexcept; + reference operator[](size_t index); + const_reference operator[](size_t index) const; }; using bool2x2 = mat; @@ -401,12 +401,12 @@ public: vec v = vec{T{0}}; T s = T{1}; - constexpr qua_base(); - constexpr qua_base(T vx, T vy, T vz, T s); - constexpr qua_base(const vec& v, T s); + qua_base(); + qua_base(T vx, T vy, T vz, T s); + qua_base(const vec& v, T s); - constexpr explicit qua_base(const vec& vs); - constexpr explicit operator vec() const; + explicit qua_base(const vec& vs); + explicit operator vec() const; }; template < typename T > @@ -430,37 +430,37 @@ public: using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; - static constexpr size_t size = 4; -public: - constexpr qua() = default; - constexpr qua(const qua&) = default; - constexpr qua& operator=(const qua&) = default; + static inline size_t size = 4; - void swap(qua& other) noexcept(is_nothrow_swappable_v); + qua() = default; + qua(const qua&) = default; + qua& operator=(const qua&) = default; - iterator begin() noexcept; - const_iterator begin() const noexcept; - iterator end() noexcept; - const_iterator end() const noexcept; + void swap(qua& other); - reverse_iterator rbegin() noexcept; - const_reverse_iterator rbegin() const noexcept; - reverse_iterator rend() noexcept; - const_reverse_iterator rend() const noexcept; + iterator begin(); + const_iterator begin() const; + iterator end(); + const_iterator end() const; - const_iterator cbegin() const noexcept; - const_iterator cend() const noexcept; - const_reverse_iterator crbegin() const noexcept; - const_reverse_iterator crend() const noexcept; + reverse_iterator rbegin(); + const_reverse_iterator rbegin() const; + reverse_iterator rend(); + const_reverse_iterator rend() const; - pointer data() noexcept; - const_pointer data() const noexcept; + const_iterator cbegin() const; + const_iterator cend() const; + const_reverse_iterator crbegin() const; + const_reverse_iterator crend() const; - constexpr reference at(size_t index); - constexpr const_reference at(size_t index) const; + pointer data(); + const_pointer data() const; - constexpr reference operator[](size_t index) noexcept; - constexpr const_reference operator[](size_t index) const noexcept; + reference at(size_t index); + const_reference at(size_t index) const; + + reference operator[](size_t index); + const_reference operator[](size_t index) const; }; using qfloat = qua; @@ -473,192 +473,192 @@ using qdouble = qua; // +operator template < typename T, size_t Size > -constexpr auto operator+(const vec& xs); +auto operator+(const vec& xs); // -operator template < typename T, size_t Size > -constexpr auto operator-(const vec& xs); +auto operator-(const vec& xs); // ~operator template < typename T, size_t Size > -constexpr auto operator~(const vec& xs); +auto operator~(const vec& xs); // !operator template < typename T, size_t Size > -constexpr auto operator!(const vec& xs); +auto operator!(const vec& xs); // operator+ template < typename T, size_t Size > -constexpr auto operator+(const vec& xs, T y); +auto operator+(const vec& xs, T y); template < typename T, size_t Size > -constexpr auto operator+(T x, const vec& ys); +auto operator+(T x, const vec& ys); template < typename T, size_t Size > -constexpr auto operator+(const vec& xs, const vec& ys); +auto operator+(const vec& xs, const vec& ys); // operator+= template < typename T, size_t Size > -constexpr vec& operator+=(vec& xs, T y); +vec& operator+=(vec& xs, T y); template < typename T, size_t Size > -constexpr vec& operator+=(vec& xs, const vec& ys); +vec& operator+=(vec& xs, const vec& ys); // operator- template < typename T, size_t Size > -constexpr auto operator-(const vec& xs, T y); +auto operator-(const vec& xs, T y); template < typename T, size_t Size > -constexpr auto operator-(T x, const vec& ys); +auto operator-(T x, const vec& ys); template < typename T, size_t Size > -constexpr auto operator-(const vec& xs, const vec& ys); +auto operator-(const vec& xs, const vec& ys); // operator-= template < typename T, size_t Size > -constexpr vec& operator-=(vec& xs, T y); +vec& operator-=(vec& xs, T y); template < typename T, size_t Size > -constexpr vec& operator-=(vec& xs, const vec& ys); +vec& operator-=(vec& xs, const vec& ys); // operator* template < typename T, size_t Size > -constexpr auto operator*(const vec& xs, T y); +auto operator*(const vec& xs, T y); template < typename T, size_t Size > -constexpr auto operator*(T x, const vec& ys); +auto operator*(T x, const vec& ys); template < typename T, size_t Size > -constexpr auto operator*(const vec& xs, const vec& ys); +auto operator*(const vec& xs, const vec& ys); // operator*= template < typename T, size_t Size > -constexpr vec& operator*=(vec& xs, T y); +vec& operator*=(vec& xs, T y); template < typename T, size_t Size > -constexpr vec& operator*=(vec& xs, const vec& ys); +vec& operator*=(vec& xs, const vec& ys); // operator/ template < typename T, size_t Size > -constexpr auto operator/(const vec& xs, T y); +auto operator/(const vec& xs, T y); template < typename T, size_t Size > -constexpr auto operator/(T x, const vec& ys); +auto operator/(T x, const vec& ys); template < typename T, size_t Size > -constexpr auto operator/(const vec& xs, const vec& ys); +auto operator/(const vec& xs, const vec& ys); // operator/= template < typename T, size_t Size > -constexpr vec& operator/=(vec& xs, T y); +vec& operator/=(vec& xs, T y); template < typename T, size_t Size > -constexpr vec& operator/=(vec& xs, const vec& ys); +vec& operator/=(vec& xs, const vec& ys); // operator& template < typename T, size_t Size > -constexpr auto operator&(const vec& xs, T y); +auto operator&(const vec& xs, T y); template < typename T, size_t Size > -constexpr auto operator&(T x, const vec& ys); +auto operator&(T x, const vec& ys); template < typename T, size_t Size > -constexpr auto operator&(const vec& xs, const vec& ys); +auto operator&(const vec& xs, const vec& ys); // operator&= template < typename T, size_t Size > -constexpr vec& operator&=(vec& xs, T y); +vec& operator&=(vec& xs, T y); template < typename T, size_t Size > -constexpr vec& operator&=(vec& xs, const vec& ys); +vec& operator&=(vec& xs, const vec& ys); // operator| template < typename T, size_t Size > -constexpr auto operator|(const vec& xs, T y); +auto operator|(const vec& xs, T y); template < typename T, size_t Size > -constexpr auto operator|(T x, const vec& ys); +auto operator|(T x, const vec& ys); template < typename T, size_t Size > -constexpr auto operator|(const vec& xs, const vec& ys); +auto operator|(const vec& xs, const vec& ys); // operator|= template < typename T, size_t Size > -constexpr vec& operator|=(vec& xs, T y); +vec& operator|=(vec& xs, T y); template < typename T, size_t Size > -constexpr vec& operator|=(vec& xs, const vec& ys); +vec& operator|=(vec& xs, const vec& ys); // operator^ template < typename T, size_t Size > -constexpr auto operator^(const vec& xs, T y); +auto operator^(const vec& xs, T y); template < typename T, size_t Size > -constexpr auto operator^(T x, const vec& ys); +auto operator^(T x, const vec& ys); template < typename T, size_t Size > -constexpr auto operator^(const vec& xs, const vec& ys); +auto operator^(const vec& xs, const vec& ys); // operator^= template < typename T, size_t Size > -constexpr vec& operator^=(vec& xs, T y); +vec& operator^=(vec& xs, T y); template < typename T, size_t Size > -constexpr vec& operator^=(vec& xs, const vec& ys); +vec& operator^=(vec& xs, const vec& ys); // operator&& template < typename T, size_t Size > -constexpr auto operator&&(const vec& xs, T y); +auto operator&&(const vec& xs, T y); template < typename T, size_t Size > -constexpr auto operator&&(T x, const vec& ys); +auto operator&&(T x, const vec& ys); template < typename T, size_t Size > -constexpr auto operator&&(const vec& xs, const vec& ys); +auto operator&&(const vec& xs, const vec& ys); // operator|| template < typename T, size_t Size > -constexpr auto operator||(const vec& xs, T y); +auto operator||(const vec& xs, T y); template < typename T, size_t Size > -constexpr auto operator||(T x, const vec& ys); +auto operator||(T x, const vec& ys); template < typename T, size_t Size > -constexpr auto operator||(const vec& xs, const vec& ys); +auto operator||(const vec& xs, const vec& ys); // operator== template < typename T, size_t Size > -constexpr bool operator==(const vec& xs, const vec& ys); +bool operator==(const vec& xs, const vec& ys); // operator!= template < typename T, size_t Size > -constexpr bool operator!=(const vec& xs, const vec& ys); +bool operator!=(const vec& xs, const vec& ys); // operator< template < typename T, size_t Size > -constexpr bool operator<(const vec& xs, const vec& ys); +bool operator<(const vec& xs, const vec& ys); ``` ### Matrix Operators @@ -667,192 +667,192 @@ constexpr bool operator<(const vec& xs, const vec& ys); // +operator template < typename T, size_t Size > -constexpr auto operator+(const mat& xs); +auto operator+(const mat& xs); // -operator template < typename T, size_t Size > -constexpr auto operator-(const mat& xs); +auto operator-(const mat& xs); // ~operator template < typename T, size_t Size > -constexpr auto operator~(const mat& xs); +auto operator~(const mat& xs); // !operator template < typename T, size_t Size > -constexpr auto operator!(const mat& xs); +auto operator!(const mat& xs); // operator+ template < typename T, size_t Size > -constexpr auto operator+(const mat& xs, T y); +auto operator+(const mat& xs, T y); template < typename T, size_t Size > -constexpr auto operator+(T x, const mat& ys); +auto operator+(T x, const mat& ys); template < typename T, size_t Size > -constexpr auto operator+(const mat& xs, const mat& ys); +auto operator+(const mat& xs, const mat& ys); // operator+= template < typename T, size_t Size > -constexpr mat& operator+=(mat& xs, T y); +mat& operator+=(mat& xs, T y); template < typename T, size_t Size > -constexpr mat& operator+=(mat& xs, const mat& ys); +mat& operator+=(mat& xs, const mat& ys); // operator- template < typename T, size_t Size > -constexpr auto operator-(const mat& xs, T y); +auto operator-(const mat& xs, T y); template < typename T, size_t Size > -constexpr auto operator-(T x, const mat& ys); +auto operator-(T x, const mat& ys); template < typename T, size_t Size > -constexpr auto operator-(const mat& xs, const mat& ys); +auto operator-(const mat& xs, const mat& ys); // operator-= template < typename T, size_t Size > -constexpr mat& operator-=(mat& xs, T y); +mat& operator-=(mat& xs, T y); template < typename T, size_t Size > -constexpr mat& operator-=(mat& xs, const mat& ys); +mat& operator-=(mat& xs, const mat& ys); // operator* template < typename T, size_t Size > -constexpr auto operator*(const mat& xs, T y); +auto operator*(const mat& xs, T y); template < typename T, size_t Size > -constexpr auto operator*(T x, const mat& ys); +auto operator*(T x, const mat& ys); template < typename T, size_t Size > -constexpr auto operator*(const vec& xs, const mat& ys); +auto operator*(const vec& xs, const mat& ys); template < typename T, size_t Size > -constexpr auto operator*(const mat& xs, const mat& ys); +auto operator*(const mat& xs, const mat& ys); // operator*= template < typename T, size_t Size > -constexpr mat& operator*=(mat& xs, T y); +mat& operator*=(mat& xs, T y); template < typename T, size_t Size > -constexpr vec& operator*=(vec& xs, const mat& ys); +vec& operator*=(vec& xs, const mat& ys); template < typename T, size_t Size > -constexpr mat& operator*=(mat& xs, const mat& ys); +mat& operator*=(mat& xs, const mat& ys); // operator/ template < typename T, size_t Size > -constexpr auto operator/(const mat& xs, T y); +auto operator/(const mat& xs, T y); template < typename T, size_t Size > -constexpr auto operator/(T x, const mat& ys); +auto operator/(T x, const mat& ys); // operator/= template < typename T, size_t Size > -constexpr mat& operator/=(mat& xs, T y); +mat& operator/=(mat& xs, T y); // operator& template < typename T, size_t Size > -constexpr auto operator&(const mat& xs, T y); +auto operator&(const mat& xs, T y); template < typename T, size_t Size > -constexpr auto operator&(T x, const mat& ys); +auto operator&(T x, const mat& ys); template < typename T, size_t Size > -constexpr auto operator&(const mat& xs, const mat& ys); +auto operator&(const mat& xs, const mat& ys); // operator&= template < typename T, size_t Size > -constexpr mat& operator&=(mat& xs, T y); +mat& operator&=(mat& xs, T y); template < typename T, size_t Size > -constexpr mat& operator&=(mat& xs, const mat& ys); +mat& operator&=(mat& xs, const mat& ys); // operator| template < typename T, size_t Size > -constexpr auto operator|(const mat& xs, T y); +auto operator|(const mat& xs, T y); template < typename T, size_t Size > -constexpr auto operator|(T x, const mat& ys); +auto operator|(T x, const mat& ys); template < typename T, size_t Size > -constexpr auto operator|(const mat& xs, const mat& ys); +auto operator|(const mat& xs, const mat& ys); // operator|= template < typename T, size_t Size > -constexpr mat& operator|=(mat& xs, T y); +mat& operator|=(mat& xs, T y); template < typename T, size_t Size > -constexpr mat& operator|=(mat& xs, const mat& ys); +mat& operator|=(mat& xs, const mat& ys); // operator^ template < typename T, size_t Size > -constexpr auto operator^(const mat& xs, T y); +auto operator^(const mat& xs, T y); template < typename T, size_t Size > -constexpr auto operator^(T x, const mat& ys); +auto operator^(T x, const mat& ys); template < typename T, size_t Size > -constexpr auto operator^(const mat& xs, const mat& ys); +auto operator^(const mat& xs, const mat& ys); // operator^= template < typename T, size_t Size > -constexpr mat& operator^=(mat& xs, T y); +mat& operator^=(mat& xs, T y); template < typename T, size_t Size > -constexpr mat& operator^=(mat& xs, const mat& ys); +mat& operator^=(mat& xs, const mat& ys); // operator&& template < typename T, size_t Size > -constexpr auto operator&&(const mat& xs, T y); +auto operator&&(const mat& xs, T y); template < typename T, size_t Size > -constexpr auto operator&&(T x, const mat& ys); +auto operator&&(T x, const mat& ys); template < typename T, size_t Size > -constexpr auto operator&&(const mat& xs, const mat& ys); +auto operator&&(const mat& xs, const mat& ys); // operator|| template < typename T, size_t Size > -constexpr auto operator||(const mat& xs, T y); +auto operator||(const mat& xs, T y); template < typename T, size_t Size > -constexpr auto operator||(T x, const mat& ys); +auto operator||(T x, const mat& ys); template < typename T, size_t Size > -constexpr auto operator||(const mat& xs, const mat& ys); +auto operator||(const mat& xs, const mat& ys); // operator== template < typename T, size_t Size > -constexpr bool operator==(const mat& xs, const mat& ys); +bool operator==(const mat& xs, const mat& ys); // operator!= template < typename T, size_t Size > -constexpr bool operator!=(const mat& xs, const mat& ys); +bool operator!=(const mat& xs, const mat& ys); // operator< template < typename T, size_t Size > -constexpr bool operator<(const mat& xs, const mat& ys); +bool operator<(const mat& xs, const mat& ys); ``` ### Quaternion Operators @@ -861,85 +861,85 @@ constexpr bool operator<(const mat& xs, const mat& ys); // +operator template < typename T > -constexpr auto operator+(const qua& xs); +auto operator+(const qua& xs); // -operator template < typename T > -constexpr auto operator-(const qua& xs); +auto operator-(const qua& xs); // operator+ template < typename T > -constexpr auto operator+(const qua& xs, const qua& ys); +auto operator+(const qua& xs, const qua& ys); // operator+= template < typename T > -constexpr qua& operator+=(qua& xs, const qua& ys); +qua& operator+=(qua& xs, const qua& ys); // operator- template < typename T > -constexpr auto operator-(const qua& xs, const qua& ys); +auto operator-(const qua& xs, const qua& ys); // operator-= template < typename T > -constexpr qua& operator-=(qua& xs, const qua& ys); +qua& operator-=(qua& xs, const qua& ys); // operator* template < typename T > -constexpr auto operator*(const qua& xs, T y); +auto operator*(const qua& xs, T y); template < typename T > -constexpr auto operator*(T x, const qua& ys); +auto operator*(T x, const qua& ys); template < typename T > -constexpr auto operator*(const vec& xs, const qua& ys); +auto operator*(const vec& xs, const qua& ys); template < typename T > -constexpr auto operator*(const qua& xs, const qua& ys); +auto operator*(const qua& xs, const qua& ys); // operator*= template < typename T > -constexpr qua& operator*=(qua& xs, T y); +qua& operator*=(qua& xs, T y); template < typename T > -constexpr vec& operator*=(vec& xs, const qua& ys); +vec& operator*=(vec& xs, const qua& ys); template < typename T > -constexpr qua& operator*=(qua& xs, const qua& ys); +qua& operator*=(qua& xs, const qua& ys); // operator/ template < typename T > -constexpr auto operator/(const qua& xs, T y); +auto operator/(const qua& xs, T y); template < typename T > -constexpr auto operator/(T x, const qua& ys); +auto operator/(T x, const qua& ys); // operator/= template < typename T > -constexpr qua& operator/=(qua& xs, T y); +qua& operator/=(qua& xs, T y); // operator== template < typename T > -constexpr bool operator==(const qua& xs, const qua& ys); +bool operator==(const qua& xs, const qua& ys); // operator!= template < typename T > -constexpr bool operator!=(const qua& xs, const qua& ys); +bool operator!=(const qua& xs, const qua& ys); // operator< template < typename T > -constexpr bool operator<(const qua& xs, const qua& ys); +bool operator<(const qua& xs, const qua& ys); ``` ### Common Functions @@ -948,83 +948,83 @@ constexpr bool operator<(const qua& xs, const qua& ys); ```cpp template < arithmetic T > -constexpr T abs(T x) noexcept; +T abs(T x); template < arithmetic T > -constexpr T sqr(T x) noexcept; +T sqr(T x); template < arithmetic T > -constexpr T sign(T x) noexcept; +T sign(T x); template < floating_point T > -constexpr T rcp(T x) noexcept; +T rcp(T x); template < floating_point T > -T floor(T x) noexcept; +T floor(T x); template < floating_point T > -T trunc(T x) noexcept; +T trunc(T x); template < floating_point T > -T round(T x) noexcept; +T round(T x); template < floating_point T > -T ceil(T x) noexcept; +T ceil(T x); template < floating_point T > -T fract(T x) noexcept; +T fract(T x); template < floating_point T > -T fmod(T x, T y) noexcept; +T fmod(T x, T y); template < floating_point T > -T modf(T x, T* y) noexcept; +T modf(T x, T* y); template < floating_point T > -T copysign(T x, T s) noexcept; +T copysign(T x, T s); template < arithmetic T > -constexpr T min(T x, T y) noexcept; +T min(T x, T y); template < arithmetic T > -constexpr T max(T x, T y) noexcept; +T max(T x, T y); template < arithmetic T > -constexpr T clamp(T x, T min_x, T max_x) noexcept; +T clamp(T x, T min_x, T max_x); template < arithmetic T > -constexpr T saturate(T x) noexcept; +T saturate(T x); template < floating_point T > -constexpr T lerp(T x, T y, T a) noexcept; +T lerp(T x, T y, T a); template < floating_point T > -constexpr T lerp(T x, T y, T x_a, T y_a) noexcept; +T lerp(T x, T y, T x_a, T y_a); template < floating_point T > -constexpr T step(T edge, T x) noexcept; +T step(T edge, T x); template < floating_point T > -constexpr T smoothstep(T edge0, T edge1, T x) noexcept; +T smoothstep(T edge0, T edge1, T x); template < floating_point T > -T fma(T x, T y, T z) noexcept; +T fma(T x, T y, T z); ``` #### Vector ```cpp template < typename T, size_t Size > -constexpr vec abs(const vec& xs); +vec abs(const vec& xs); template < typename T, size_t Size > -constexpr vec sqr(const vec& xs); +vec sqr(const vec& xs); template < typename T, size_t Size > -constexpr vec sign(const vec& xs); +vec sign(const vec& xs); template < typename T, size_t Size > -constexpr vec rcp(const vec& xs); +vec rcp(const vec& xs); template < typename T, size_t Size > vec floor(const vec& xs); @@ -1057,61 +1057,61 @@ template < typename T, size_t Size > vec copysign(const vec& xs, const vec& ss); template < typename T, size_t Size > -constexpr T min(const vec& xs); +T min(const vec& xs); template < typename T, size_t Size > -constexpr vec min(const vec& xs, T y); +vec min(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec min(T x, const vec& ys); +vec min(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec min(const vec& xs, const vec& ys); +vec min(const vec& xs, const vec& ys); template < typename T, size_t Size > -constexpr T max(const vec& xs); +T max(const vec& xs); template < typename T, size_t Size > -constexpr vec max(const vec& xs, T y); +vec max(const vec& xs, T y); template < typename T, size_t Size > -constexpr vec max(T x, const vec& ys); +vec max(T x, const vec& ys); template < typename T, size_t Size > -constexpr vec max(const vec& xs, const vec& ys); +vec max(const vec& xs, const vec& ys); template < typename T, size_t Size > -constexpr vec clamp(const vec& xs, T min_x, T max_x); +vec clamp(const vec& xs, T min_x, T max_x); template < typename T, size_t Size > -constexpr vec clamp(const vec& xs, const vec& min_xs, const vec& max_xs); +vec clamp(const vec& xs, const vec& min_xs, const vec& max_xs); template < typename T, size_t Size > -constexpr vec saturate(const vec& xs); +vec saturate(const vec& xs); template < typename T, size_t Size > -constexpr vec lerp(const vec& xs, const vec& ys, T a); +vec lerp(const vec& xs, const vec& ys, T a); template < typename T, size_t Size > -constexpr vec lerp(const vec& xs, const vec& ys, T x_a, T y_a); +vec lerp(const vec& xs, const vec& ys, T x_a, T y_a); template < typename T, size_t Size > -constexpr vec lerp(const vec& xs, const vec& ys, const vec& as); +vec lerp(const vec& xs, const vec& ys, const vec& as); template < typename T, size_t Size > -constexpr vec lerp(const vec& xs, const vec& ys, const vec& xs_a, const vec& ys_a); +vec lerp(const vec& xs, const vec& ys, const vec& xs_a, const vec& ys_a); template < typename T, size_t Size > -constexpr vec step(T edge, const vec& xs); +vec step(T edge, const vec& xs); template < typename T, size_t Size > -constexpr vec step(const vec& edges, const vec& xs); +vec step(const vec& edges, const vec& xs); template < typename T, size_t Size > -constexpr vec smoothstep(T edge0, T edge1, const vec& xs); +vec smoothstep(T edge0, T edge1, const vec& xs); template < typename T, size_t Size > -constexpr vec smoothstep(const vec& edges0, const vec& edges1, const vec& xs); +vec smoothstep(const vec& edges0, const vec& edges1, const vec& xs); template < typename T, size_t Size > vec fma(const vec& as, const vec& bs, const vec& cs); @@ -1139,65 +1139,65 @@ qua slerp(const qua& unit_xs, const qua& unit_ys, T a); ```cpp template < floating_point T > -constexpr T radians(T degrees) noexcept; +T radians(T degrees); template < floating_point T > -constexpr T degrees(T radians) noexcept; +T degrees(T radians); template < floating_point T > -T sin(T x) noexcept; +T sin(T x); template < floating_point T > -T cos(T x) noexcept; +T cos(T x); template < floating_point T > -T tan(T x) noexcept; +T tan(T x); template < floating_point T > -T asin(T x) noexcept; +T asin(T x); template < floating_point T > -T acos(T x) noexcept; +T acos(T x); template < floating_point T > -T atan(T x) noexcept; +T atan(T x); template < floating_point T > -T atan2(T y, T x) noexcept; +T atan2(T y, T x); template < floating_point T > -T sinh(T x) noexcept; +T sinh(T x); template < floating_point T > -T cosh(T x) noexcept; +T cosh(T x); template < floating_point T > -T tanh(T x) noexcept; +T tanh(T x); template < floating_point T > -T asinh(T x) noexcept; +T asinh(T x); template < floating_point T > -T acosh(T x) noexcept; +T acosh(T x); template < floating_point T > -T atanh(T x) noexcept; +T atanh(T x); template < floating_point T > -pair sincos(T x) noexcept; +pair sincos(T x); template < floating_point T > -void sincos(T x, T* s, T* c) noexcept; +void sincos(T x, T* s, T* c); ``` #### Vector ```cpp template < typename T, size_t Size > -constexpr vec radians(const vec& degrees); +vec radians(const vec& degrees); template < typename T, size_t Size > -constexpr vec degrees(const vec& radians); +vec degrees(const vec& radians); template < typename T, size_t Size > vec sin(const vec& xs); @@ -1251,25 +1251,25 @@ void sincos(const vec& xs, vec* ss, vec* cs); ```cpp template < floating_point T > -T pow(T x, T y) noexcept; +T pow(T x, T y); template < floating_point T > -T exp(T x) noexcept; +T exp(T x); template < floating_point T > -T log(T x) noexcept; +T log(T x); template < floating_point T > -T exp2(T x) noexcept; +T exp2(T x); template < floating_point T > -T log2(T x) noexcept; +T log2(T x); template < floating_point T > -T sqrt(T x) noexcept; +T sqrt(T x); template < floating_point T > -T rsqrt(T x) noexcept; +T rsqrt(T x); ``` #### Vector @@ -1303,44 +1303,44 @@ vec rsqrt(const vec& xs); ```cpp template < arithmetic T > -constexpr T dot(T x, T y) noexcept; +T dot(T x, T y); template < arithmetic T > -constexpr T length(T x) noexcept; +T length(T x); template < arithmetic T > -constexpr T rlength(T x) noexcept; +T rlength(T x); template < arithmetic T > -constexpr T length2(T x) noexcept; +T length2(T x); template < arithmetic T > -constexpr T rlength2(T x) noexcept; +T rlength2(T x); template < arithmetic T > -constexpr T distance(T x, T y) noexcept; +T distance(T x, T y); template < arithmetic T > -constexpr T distance2(T x, T y) noexcept; +T distance2(T x, T y); template < floating_point T > -T normalize(T x) noexcept; +T normalize(T x); template < floating_point T > -constexpr T faceforward(T n, T i, T nref) noexcept; +T faceforward(T n, T i, T nref); template < floating_point T > -constexpr T reflect(T i, T n) noexcept; +T reflect(T i, T n); template < floating_point T > -T refract(T i, T n, T eta) noexcept; +T refract(T i, T n, T eta); ``` #### Vector ```cpp template < typename T, size_t Size > -constexpr T dot(const vec& xs, const vec& ys); +T dot(const vec& xs, const vec& ys); template < typename T, size_t Size > T length(const vec& xs); @@ -1349,31 +1349,31 @@ template < typename T, size_t Size > T rlength(const vec& xs); template < typename T, size_t Size > -constexpr T length2(const vec& xs); +T length2(const vec& xs); template < typename T, size_t Size > -constexpr T rlength2(const vec& xs); +T rlength2(const vec& xs); template < typename T, size_t Size > T distance(const vec& xs, const vec& ys); template < typename T, size_t Size > -constexpr T distance2(const vec& xs, const vec& ys); +T distance2(const vec& xs, const vec& ys); template < typename T > -constexpr T cross(const vec& xs, const vec& ys); +T cross(const vec& xs, const vec& ys); template < typename T > -constexpr vec cross(const vec& xs, const vec& ys); +vec cross(const vec& xs, const vec& ys); template < typename T, size_t Size > vec normalize(const vec& xs); template < typename T, size_t Size > -constexpr vec faceforward(const vec& n, const vec& i, const vec& nref); +vec faceforward(const vec& n, const vec& i, const vec& nref); template < typename T, size_t Size > -constexpr vec reflect(const vec& i, const vec& n); +vec reflect(const vec& i, const vec& n); template < typename T, size_t Size > vec refract(const vec& i, const vec& n, T eta); @@ -1383,7 +1383,7 @@ vec refract(const vec& i, const vec& n, T eta); ```cpp template < typename T > -constexpr T dot(const qua& xs, const qua& ys); +T dot(const qua& xs, const qua& ys); template < typename T > T length(const qua& xs); @@ -1392,10 +1392,10 @@ template < typename T > T rlength(const qua& xs); template < typename T > -constexpr T length2(const qua& xs); +T length2(const qua& xs); template < typename T > -constexpr T rlength2(const qua& xs); +T rlength2(const qua& xs); template < typename T > T distance(const qua& xs, const qua& ys); @@ -1410,362 +1410,362 @@ qua normalize(const qua& xs); ```cpp template < arithmetic T > -constexpr bool any(T x) noexcept; +bool any(T x); template < arithmetic T > -constexpr bool all(T x) noexcept; +bool all(T x); template < arithmetic T > -constexpr bool approx(T x, T y) noexcept; +bool approx(T x, T y); template < arithmetic T > -constexpr bool approx(T x, T y, T epsilon) noexcept; +bool approx(T x, T y, T epsilon); template < arithmetic T > -constexpr bool less(T x, T y) noexcept; +bool less(T x, T y); template < arithmetic T > -constexpr bool less_equal(T x, T y) noexcept; +bool less_equal(T x, T y); template < arithmetic T > -constexpr bool greater(T x, T y) noexcept; +bool greater(T x, T y); template < arithmetic T > -constexpr bool greater_equal(T x, T y) noexcept; +bool greater_equal(T x, T y); template < arithmetic T > -constexpr bool equal_to(T x, T y) noexcept; +bool equal_to(T x, T y); template < arithmetic T > -constexpr bool not_equal_to(T x, T y) noexcept; +bool not_equal_to(T x, T y); ``` #### Vector ```cpp -template < typename T, std::size_t Size - , typename U = decltype(any(std::declval())) > -constexpr U any(const vec& xs); +template < typename T, size_t Size + , typename U = decltype(any(declval())) > +U any(const vec& xs); -template < typename T, std::size_t Size - , typename U = decltype(all(std::declval())) > -constexpr U all(const vec& xs); +template < typename T, size_t Size + , typename U = decltype(all(declval())) > +U all(const vec& xs); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = decltype(approx( - std::declval(), - std::declval())) > -constexpr vec approx(const vec& xs, const vec& ys); + declval(), + declval())) > +vec approx(const vec& xs, const vec& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = decltype(approx( - std::declval(), - std::declval(), - std::declval())) > -constexpr vec approx(const vec& xs, const vec& ys, T epsilon); + declval(), + declval(), + declval())) > +vec approx(const vec& xs, const vec& ys, T epsilon); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = decltype(less( - std::declval(), - std::declval())) > -constexpr vec less(const vec& xs, const vec& ys); + declval(), + declval())) > +vec less(const vec& xs, const vec& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = decltype(less_equal( - std::declval(), - std::declval())) > -constexpr vec less_equal(const vec& xs, const vec& ys); + declval(), + declval())) > +vec less_equal(const vec& xs, const vec& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = decltype(greater( - std::declval(), - std::declval())) > -constexpr vec greater(const vec& xs, const vec& ys); + declval(), + declval())) > +vec greater(const vec& xs, const vec& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = decltype(greater_equal( - std::declval(), - std::declval())) > -constexpr vec greater_equal(const vec& xs, const vec& ys); + declval(), + declval())) > +vec greater_equal(const vec& xs, const vec& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = decltype(equal_to( - std::declval(), - std::declval())) > -constexpr vec equal_to(const vec& xs, const vec& ys); + declval(), + declval())) > +vec equal_to(const vec& xs, const vec& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = decltype(not_equal_to( - std::declval(), - std::declval())) > -constexpr vec not_equal_to(const vec& xs, const vec& ys); + declval(), + declval())) > +vec not_equal_to(const vec& xs, const vec& ys); ``` #### Matrix ```cpp -template < typename T, std::size_t Size - , typename U = decltype(any(std::declval>())) > -constexpr U any(const mat& xs); +template < typename T, size_t Size + , typename U = decltype(any(declval>())) > +U any(const mat& xs); -template < typename T, std::size_t Size - , typename U = decltype(all(std::declval>())) > -constexpr U all(const mat& xs); +template < typename T, size_t Size + , typename U = decltype(all(declval>())) > +U all(const mat& xs); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = typename decltype(approx( - std::declval>(), - std::declval>()))::component_type > -constexpr mat approx(const mat& xs, const mat& ys); + declval>(), + declval>()))::component_type > +mat approx(const mat& xs, const mat& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = typename decltype(approx( - std::declval>(), - std::declval>(), - std::declval()))::component_type > -constexpr mat approx(const mat& xs, const mat& ys, T epsilon); + declval>(), + declval>(), + declval()))::component_type > +mat approx(const mat& xs, const mat& ys, T epsilon); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = typename decltype(less( - std::declval>(), - std::declval>()))::component_type > -constexpr mat less(const mat& xs, const mat& ys); + declval>(), + declval>()))::component_type > +mat less(const mat& xs, const mat& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = typename decltype(less_equal( - std::declval>(), - std::declval>()))::component_type > -constexpr mat less_equal(const mat& xs, const mat& ys); + declval>(), + declval>()))::component_type > +mat less_equal(const mat& xs, const mat& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = typename decltype(greater( - std::declval>(), - std::declval>()))::component_type > -constexpr mat greater(const mat& xs, const mat& ys); + declval>(), + declval>()))::component_type > +mat greater(const mat& xs, const mat& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = typename decltype(greater_equal( - std::declval>(), - std::declval>()))::component_type > -constexpr mat greater_equal(const mat& xs, const mat& ys); + declval>(), + declval>()))::component_type > +mat greater_equal(const mat& xs, const mat& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = typename decltype(equal_to( - std::declval>(), - std::declval>()))::component_type > -constexpr mat equal_to(const mat& xs, const mat& ys); + declval>(), + declval>()))::component_type > +mat equal_to(const mat& xs, const mat& ys); -template < typename T, std::size_t Size +template < typename T, size_t Size , typename U = typename decltype(not_equal_to( - std::declval>(), - std::declval>()))::component_type > -constexpr mat not_equal_to(const mat& xs, const mat& ys); + declval>(), + declval>()))::component_type > +mat not_equal_to(const mat& xs, const mat& ys); ``` #### Quaternion ```cpp template < typename T - , typename U = decltype(any(std::declval>())) > -constexpr U any(const qua& xs); + , typename U = decltype(any(declval>())) > +U any(const qua& xs); template < typename T - , typename U = decltype(all(std::declval>())) > -constexpr U all(const qua& xs); + , typename U = decltype(all(declval>())) > +U all(const qua& xs); template < typename T , typename U = typename decltype(approx( - std::declval>(), - std::declval>()))::component_type > -constexpr vec approx(const qua& xs, const qua& ys); + declval>(), + declval>()))::component_type > +vec approx(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(approx( - std::declval>(), - std::declval>(), - std::declval()))::component_type > -constexpr vec approx(const qua& xs, const qua& ys, T epsilon); + declval>(), + declval>(), + declval()))::component_type > +vec approx(const qua& xs, const qua& ys, T epsilon); template < typename T , typename U = typename decltype(less( - std::declval>(), - std::declval>()))::component_type > -constexpr vec less(const qua& xs, const qua& ys); + declval>(), + declval>()))::component_type > +vec less(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(less_equal( - std::declval>(), - std::declval>()))::component_type > -constexpr vec less_equal(const qua& xs, const qua& ys); + declval>(), + declval>()))::component_type > +vec less_equal(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(greater( - std::declval>(), - std::declval>()))::component_type > -constexpr vec greater(const qua& xs, const qua& ys); + declval>(), + declval>()))::component_type > +vec greater(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(greater_equal( - std::declval>(), - std::declval>()))::component_type > -constexpr vec greater_equal(const qua& xs, const qua& ys); + declval>(), + declval>()))::component_type > +vec greater_equal(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(equal_to( - std::declval>(), - std::declval>()))::component_type > -constexpr vec equal_to(const qua& xs, const qua& ys); + declval>(), + declval>()))::component_type > +vec equal_to(const qua& xs, const qua& ys); template < typename T , typename U = typename decltype(not_equal_to( - std::declval>(), - std::declval>()))::component_type > -constexpr vec not_equal_to(const qua& xs, const qua& ys); + declval>(), + declval>()))::component_type > +vec not_equal_to(const qua& xs, const qua& ys); ``` ### Matrix Functions ```cpp template < typename T > -constexpr mat transpose(const mat& m); +mat transpose(const mat& m); template < typename T > -constexpr mat transpose(const mat& m); +mat transpose(const mat& m); template < typename T > -constexpr mat transpose(const mat& m); +mat transpose(const mat& m); template < typename T > -constexpr T determinant(const mat& m); +T determinant(const mat& m); template < typename T > -constexpr T determinant(const mat& m); +T determinant(const mat& m); template < typename T > -constexpr T determinant(const mat& m); +T determinant(const mat& m); template < typename T > -constexpr mat inverse(const mat& m); +mat inverse(const mat& m); template < typename T > -constexpr mat inverse(const mat& m); +mat inverse(const mat& m); template < typename T > -constexpr mat inverse(const mat& m); +mat inverse(const mat& m); ``` ### Quaternion Functions ```cpp template < typename T > -constexpr qua conjugate(const qua& q); +qua conjugate(const qua& q); template < typename T > -constexpr qua inverse(const qua& q); +qua inverse(const qua& q); ``` ### Units ```cpp -template < typename T > inline constexpr vec zero2; -template < typename T > inline constexpr vec zero3; -template < typename T > inline constexpr vec zero4; +template < typename T > inline vec zero2; +template < typename T > inline vec zero3; +template < typename T > inline vec zero4; -template < typename T > inline constexpr vec unit2; -template < typename T > inline constexpr vec unit3; -template < typename T > inline constexpr vec unit4; +template < typename T > inline vec unit2; +template < typename T > inline vec unit3; +template < typename T > inline vec unit4; -template < typename T > inline constexpr vec unit2_x; -template < typename T > inline constexpr vec unit2_y; +template < typename T > inline vec unit2_x; +template < typename T > inline vec unit2_y; -template < typename T > inline constexpr vec unit3_x; -template < typename T > inline constexpr vec unit3_y; -template < typename T > inline constexpr vec unit3_z; +template < typename T > inline vec unit3_x; +template < typename T > inline vec unit3_y; +template < typename T > inline vec unit3_z; -template < typename T > inline constexpr vec unit4_x; -template < typename T > inline constexpr vec unit4_y; -template < typename T > inline constexpr vec unit4_z; -template < typename T > inline constexpr vec unit4_w; +template < typename T > inline vec unit4_x; +template < typename T > inline vec unit4_y; +template < typename T > inline vec unit4_z; +template < typename T > inline vec unit4_w; -template < typename T > inline constexpr mat zero2x2; -template < typename T > inline constexpr mat zero3x3; -template < typename T > inline constexpr mat zero4x4; +template < typename T > inline mat zero2x2; +template < typename T > inline mat zero3x3; +template < typename T > inline mat zero4x4; -template < typename T > inline constexpr mat unit2x2; -template < typename T > inline constexpr mat unit3x3; -template < typename T > inline constexpr mat unit4x4; +template < typename T > inline mat unit2x2; +template < typename T > inline mat unit3x3; +template < typename T > inline mat unit4x4; -template < typename T > inline constexpr mat identity2x2; -template < typename T > inline constexpr mat identity3x3; -template < typename T > inline constexpr mat identity4x4; +template < typename T > inline mat identity2x2; +template < typename T > inline mat identity3x3; +template < typename T > inline mat identity4x4; -template < typename T > inline constexpr qua qidentity; +template < typename T > inline qua qidentity; ``` ### Cast ```cpp template < arithmetic To, arithmetic From > -constexpr To cast_to(From x) noexcept; +To cast_to(From x); template < typename To, typename From, size_t Size > -constexpr vec cast_to(const vec& v); +vec cast_to(const vec& v); template < typename To, typename From, size_t Size > -constexpr mat cast_to(const mat& m); +mat cast_to(const mat& m); template < typename To, typename From > -constexpr qua cast_to(const qua& q); +qua cast_to(const qua& q); ``` ### Access ```cpp template < typename T, size_t Size > -constexpr T component(const vec& v, size_t index); +T component(const vec& v, size_t index); template < typename T, size_t Size > -constexpr vec component(vec v, size_t index, T x); +vec component(vec v, size_t index, T x); template < typename T, size_t Size > -constexpr vec row(const mat& m, size_t index); +vec row(const mat& m, size_t index); template < typename T, size_t Size > -constexpr mat row(mat m, size_t index, const vec& v); +mat row(mat m, size_t index, const vec& v); template < typename T, size_t Size > -constexpr vec column(const mat& m, size_t index); +vec column(const mat& m, size_t index); template < typename T, size_t Size > -constexpr mat column(const mat& m, size_t index, const vec& v); +mat column(const mat& m, size_t index, const vec& v); template < typename T > -constexpr T real(const qua& q); +T real(const qua& q); template < typename T > -constexpr qua real(qua q, T real); +qua real(qua q, T real); template < typename T > -constexpr vec imag(const qua& q); +vec imag(const qua& q); template < typename T > -constexpr qua imag(qua q, const vec& imag); +qua imag(qua q, const vec& imag); ``` ### Matrix Transform 3D ```cpp template < typename T > -constexpr mat translate(T x, T y, T z); +mat translate(T x, T y, T z); template < typename T > -constexpr mat translate(const mat& m, T x, T y, T z); +mat translate(const mat& m, T x, T y, T z); template < typename T > -constexpr mat translate(const vec& v); +mat translate(const vec& v); template < typename T > -constexpr mat translate(const mat& m, const vec& v); +mat translate(const mat& m, const vec& v); template < typename T > mat rotate(const qua& q); @@ -1798,16 +1798,16 @@ template < typename T > mat rotate_z(const mat& m, T angle); template < typename T > -constexpr mat scale(T x, T y, T z); +mat scale(T x, T y, T z); template < typename T > -constexpr mat scale(const mat& m, T x, T y, T z); +mat scale(const mat& m, T x, T y, T z); template < typename T > -constexpr mat scale(const vec& v); +mat scale(const vec& v); template < typename T > -constexpr mat scale(const mat& m, const vec& v); +mat scale(const mat& m, const vec& v); template < typename T > mat look_at_lh(const vec& eye, const vec& at, const vec& up); @@ -1820,16 +1820,16 @@ mat look_at_rh(const vec& eye, const vec& at, const vec& ```cpp template < typename T > -constexpr mat translate(T x, T y); +mat translate(T x, T y); template < typename T > -constexpr mat translate(const mat& m, T x, T y); +mat translate(const mat& m, T x, T y); template < typename T > -constexpr mat translate(const vec& v); +mat translate(const vec& v); template < typename T > -constexpr mat translate(const mat& m, const vec& v); +mat translate(const mat& m, const vec& v); template < typename T > mat rotate(T angle); @@ -1838,40 +1838,40 @@ template < typename T > mat rotate(const mat& m, T angle); template < typename T > -constexpr mat scale(T x, T y); +mat scale(T x, T y); template < typename T > -constexpr mat scale(const mat& m, T x, T y); +mat scale(const mat& m, T x, T y); template < typename T > -constexpr mat scale(const vec& v); +mat scale(const vec& v); template < typename T > -constexpr mat scale(const mat& m, const vec& v); +mat scale(const mat& m, const vec& v); template < typename T > -constexpr mat shear(T x, T y); +mat shear(T x, T y); template < typename T > -constexpr mat shear(const mat& m, T x, T y); +mat shear(const mat& m, T x, T y); template < typename T > -constexpr mat shear(const vec& v); +mat shear(const vec& v); template < typename T > -constexpr mat shear(const mat& m, const vec& v); +mat shear(const mat& m, const vec& v); template < typename T > -constexpr mat shear_x(T y); +mat shear_x(T y); template < typename T > -constexpr mat shear_x(const mat& m, T y); +mat shear_x(const mat& m, T y); template < typename T > -constexpr mat shear_y(T x); +mat shear_y(T x); template < typename T > -constexpr mat shear_y(const mat& m, T x); +mat shear_y(const mat& m, T x); ``` ### Matrix Projections @@ -1933,10 +1933,10 @@ template < typename T > vec rotate(const vec& v, T angle, const vec& axis); template < typename T, size_t Size > -constexpr vec project(const vec& v, const vec& normal); +vec project(const vec& v, const vec& normal); template < typename T, size_t Size > -constexpr vec perpendicular(const vec& v, const vec& normal); +vec perpendicular(const vec& v, const vec& normal); ``` ### Quaternion Transform From 302987a4222ff3fb52e219b7e66a79642296f3a0 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Wed, 24 Feb 2021 04:50:05 +0700 Subject: [PATCH 15/15] remove fma functions --- README.md | 6 ------ headers/vmath.hpp/vmath_fun.hpp | 6 ------ headers/vmath.hpp/vmath_vec_fun.hpp | 5 ----- untests/vmath_fix_tests.cpp | 4 ---- untests/vmath_fun_tests.cpp | 2 -- untests/vmath_vec_fun_tests.cpp | 2 -- 6 files changed, 25 deletions(-) diff --git a/README.md b/README.md index 6103240..53a0e31 100644 --- a/README.md +++ b/README.md @@ -1006,9 +1006,6 @@ T step(T edge, T x); template < floating_point T > T smoothstep(T edge0, T edge1, T x); - -template < floating_point T > -T fma(T x, T y, T z); ``` #### Vector @@ -1112,9 +1109,6 @@ vec smoothstep(T edge0, T edge1, const vec& xs); template < typename T, size_t Size > vec smoothstep(const vec& edges0, const vec& edges1, const vec& xs); - -template < typename T, size_t Size > -vec fma(const vec& as, const vec& bs, const vec& cs); ``` #### Quaternion diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index e87e262..8da26fc 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -138,12 +138,6 @@ namespace vmath_hpp const T t = clamp((x - edge0) * rcp(edge1 - edge0), T{0}, T{1}); return t * t * (T{3} - T{2} * t); } - - template < typename T > - [[nodiscard]] std::enable_if_t, T> - fma(T x, T y, T z) noexcept { - return std::fma(x, y, z); - } } // diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 9cf110e..69c3c6e 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -632,11 +632,6 @@ namespace vmath_hpp [[nodiscard]] constexpr vec smoothstep(const vec& edges0, const vec& edges1, const vec& xs) { return map_join([](T edge0, T edge1, T x) { return smoothstep(edge0, edge1, x); }, edges0, edges1, xs); } - - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec fma(const vec& as, const vec& bs, const vec& cs) { - return map_join([](T a, T b, T c) { return fma(a, b, c); }, as, bs, cs); - } } // diff --git a/untests/vmath_fix_tests.cpp b/untests/vmath_fix_tests.cpp index 1d0d4ad..1af899d 100644 --- a/untests/vmath_fix_tests.cpp +++ b/untests/vmath_fix_tests.cpp @@ -47,8 +47,6 @@ namespace constexpr friend fix step(const fix& e, const fix& l) { using vmath_hpp::step; return fix{step(e.underlying(), l.underlying())}; } constexpr friend fix smoothstep(const fix& e0, const fix& e1, const fix& l) { using vmath_hpp::smoothstep; return fix{smoothstep(e0.underlying(), e1.underlying(), l.underlying())}; } - constexpr friend fix fma(const fix& x, const fix& y, const fix& z) { using vmath_hpp::fma; return fix{fma(x.underlying(), y.underlying(), z.underlying())}; } - // constexpr friend fix any(const fix& l) { using vmath_hpp::any; return fix{any(l.underlying())}; } @@ -199,8 +197,6 @@ namespace vmath_hpp template fix2f step(const fix2f&, const fix2f&); template fix2f smoothstep(fix, fix, const fix2f&); template fix2f smoothstep(const fix2f&, const fix2f&, const fix2f&); - - template fix2f fma(const fix2f&, const fix2f&, const fix2f&); } namespace vmath_hpp diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index 4817f09..9903781 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -105,8 +105,6 @@ TEST_CASE("vmath/fun") { STATIC_CHECK(step(0.5f, 0.4f) == uapprox(0.f)); STATIC_CHECK(step(0.5f, 0.6f) == uapprox(1.f)); STATIC_CHECK(smoothstep(0.f, 1.f, 0.1f) == uapprox(0.028f)); - - CHECK(fma(2.f, 3.f, 4.f) == uapprox(10.f)); } SUBCASE("Geometric Functions") { diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 31b4915..262f1ec 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -249,8 +249,6 @@ TEST_CASE("vmath/vec_fun") { STATIC_CHECK(smoothstep(0.f, 1.f, float2(0.1f)) == uapprox2(0.028f)); STATIC_CHECK(smoothstep(float2(0.f), float2(1.f), float2(0.1f)) == uapprox2(0.028f)); - - CHECK_FALSE(fma(float2(2.f), float2(3.f), float2(4.f)).x == uapprox(12.f)); } SUBCASE("Geometric Functions") {