From ec5d2d59e3e53875164c637d75cb0c74b055e478 Mon Sep 17 00:00:00 2001 From: BlackMATov Date: Tue, 26 Jan 2021 01:45:56 +0700 Subject: [PATCH] qua without fold details --- headers/vmath.hpp/vmath_ext.hpp | 4 +- headers/vmath.hpp/vmath_qua.hpp | 95 +++++++-------- headers/vmath.hpp/vmath_qua_fun.hpp | 176 ++-------------------------- untests/vmath_qua_fun_tests.cpp | 26 ---- untests/vmath_qua_tests.cpp | 53 ++++----- 5 files changed, 77 insertions(+), 277 deletions(-) diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index de68b97..64c30aa 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -77,7 +77,7 @@ namespace vmath_hpp::detail template < typename T > [[nodiscard]] std::size_t hash(const qua& q) noexcept { - return fold_join(hash_combiner{}, std::size_t{}, q); + return hash(vec{q}); } } @@ -131,7 +131,7 @@ namespace vmath_hpp template < typename To, typename From > [[nodiscard]] constexpr qua cast_to(const qua& q) { - return detail::map_join([](From x){ return cast_to(x); }, q); + return qua(cast_to(vec{q})); } } diff --git a/headers/vmath.hpp/vmath_qua.hpp b/headers/vmath.hpp/vmath_qua.hpp index b316969..7b367d2 100644 --- a/headers/vmath.hpp/vmath_qua.hpp +++ b/headers/vmath.hpp/vmath_qua.hpp @@ -11,57 +11,15 @@ #include "vmath_vec.hpp" #include "vmath_vec_fun.hpp" -namespace vmath_hpp::detail -{ - template < typename T > - class qua_base { - public: - T x{0}, y{0}, z{0}, w{1}; - public: - constexpr qua_base() = default; - - constexpr explicit qua_base(T w) - : x{0}, y{0}, z{0}, w{w} {} - - constexpr qua_base(T x, T y, T z, T w) - : x{x}, y{y}, z{z}, w{w} {} - - constexpr qua_base(const vec& xyz, T w) - : x{xyz[0]}, y{xyz[1]}, z{xyz[2]}, w{w} {} - - constexpr qua_base(const vec& xyzw) - : x{xyzw[0]}, y{xyzw[1]}, z{xyzw[2]}, w{xyzw[3]} {} - - [[nodiscard]] constexpr T& operator[](std::size_t index) noexcept { - switch ( index ) { - default: - case 0: return x; - case 1: return y; - case 2: return z; - case 3: return w; - } - } - - [[nodiscard]] constexpr const T& operator[](std::size_t index) const noexcept { - switch ( index ) { - default: - case 0: return x; - case 1: return y; - case 2: return z; - case 3: return w; - } - } - }; -} - namespace vmath_hpp { template < typename T > - class qua final : public detail::qua_base { + class qua final { + public: + vec v{0}; + T s{1}; public: using self_type = qua; - using base_type = detail::qua_base; - public: using component_type = T; using pointer = component_type*; @@ -77,13 +35,26 @@ 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; @@ -114,6 +85,26 @@ namespace vmath_hpp return &(*this)[0]; } + [[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; + } + } + [[nodiscard]] constexpr reference at(std::size_t index) { if ( index >= size ) { throw std::out_of_range("qua::at"); @@ -132,10 +123,12 @@ namespace vmath_hpp namespace vmath_hpp { - // qua + // vec template < typename T > - qua(T) -> qua; + vec(const qua&) -> vec; + + // qua template < typename T > qua(T, T, T, T) -> qua; diff --git a/headers/vmath.hpp/vmath_qua_fun.hpp b/headers/vmath.hpp/vmath_qua_fun.hpp index 5c83b55..f4ce40f 100644 --- a/headers/vmath.hpp/vmath_qua_fun.hpp +++ b/headers/vmath.hpp/vmath_qua_fun.hpp @@ -11,153 +11,8 @@ #include "vmath_fun.hpp" #include "vmath_qua.hpp" -namespace vmath_hpp::detail::impl -{ - template < typename A, typename F, std::size_t... Is > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( - F&& f, - const qua& a, - std::index_sequence - ) -> qua()))> - { - return { f(a[Is])... }; - } - - template < typename A, typename B, typename F, std::size_t... Is > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( - F&& f, - const qua& a, - const qua& b, - std::index_sequence - ) -> qua(), - std::declval()))> - { - return { f(a[Is], b[Is])... }; - } - - template < typename A, typename B, typename C, typename F, std::size_t... Is > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join_impl( - F&& f, - const qua& a, - const qua& b, - const qua& c, - std::index_sequence - ) -> qua(), - std::declval(), - std::declval()))> - { - return { f(a[Is], b[Is], c[Is])... }; - } - - template < typename A, typename B, typename F, std::size_t... Is > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join_impl( - F&& f, - A init, - const qua& b, - std::index_sequence - ) -> A { - return ((init = f(std::move(init), b[Is])), ...); - } - - template < typename A, typename B, typename C, typename F, std::size_t... Is > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join_impl( - F&& f, - A init, - const qua& b, - const qua& c, - std::index_sequence - ) -> A { - return ((init = f(std::move(init), b[Is], c[Is])), ...); - } - - template < typename A, typename F, std::size_t I, std::size_t... Is > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold1_join_impl( - F&& f, - const qua& a, - std::index_sequence - ) -> A { - A init = a[I]; - return ((init = f(std::move(init), a[Is])), ...); - } -} - -namespace vmath_hpp::detail -{ - template < typename A, typename F > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto map_join( - F&& f, - const qua& a - ) { - return impl::map_join_impl( - std::forward(f), a, std::make_index_sequence<4>{}); - } - - 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 impl::map_join_impl( - std::forward(f), a, b, std::make_index_sequence<4>{}); - } - - 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 impl::map_join_impl( - std::forward(f), a, b, c, std::make_index_sequence<4>{}); - } - - template < typename A, typename B, typename F > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold_join( - F&& f, - A init, - const qua& b - ) { - return impl::fold_join_impl( - std::forward(f), std::move(init), b, std::make_index_sequence<4>{}); - } - - 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 impl::fold_join_impl( - std::forward(f), std::move(init), b, c, std::make_index_sequence<4>{}); - } - - template < typename A, typename F > - [[nodiscard]] constexpr VMATH_HPP_FORCE_INLINE - auto fold1_join( - F&& f, - const qua& a - ) { - return impl::fold1_join_impl( - std::forward(f), a, std::make_index_sequence<4>{}); - } -} +#include "vmath_vec.hpp" +#include "vmath_vec_fun.hpp" // // Operators @@ -176,14 +31,14 @@ namespace vmath_hpp template < typename T > [[nodiscard]] constexpr qua operator-(const qua& xs) { - return map_join([](T x){ return -x; }, xs); + return qua(-vec{xs}); } // operator+ template < typename T > [[nodiscard]] constexpr qua operator+(const qua& xs, const qua& ys) { - return map_join([](T x, T y){ return x + y; }, xs, ys); + return qua(vec{xs} + vec{ys}); } // operator+= @@ -197,7 +52,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] constexpr qua operator-(const qua& xs, const qua& ys) { - return map_join([](T x, T y){ return x - y; }, xs, ys); + return qua(vec{xs} - vec{ys}); } // operator-= @@ -211,32 +66,23 @@ namespace vmath_hpp template < typename T > [[nodiscard]] constexpr bool operator==(const qua& xs, const qua& ys) { - return fold_join([](bool acc, T x, T y){ - return acc && x == y; - }, true, xs, ys); + return vec{xs} == vec{ys}; } // operator!= template < typename T > [[nodiscard]] constexpr bool operator!=(const qua& xs, const qua& ys) { - return fold_join([](bool acc, T x, T y){ - return acc || x != y; - }, false, xs, ys); + return vec{xs} != vec{ys}; } // operator< template < typename T > [[nodiscard]] constexpr bool operator<(const qua& xs, const qua& ys) { - for ( std::size_t i = 0; i < 4; ++i ) { - if ( xs[i] < ys[i] ) { - return true; - } - if ( ys[i] < xs[i] ) { - return false; - } - } - return false; + return vec{xs} < vec{ys}; + } +} + } } diff --git a/untests/vmath_qua_fun_tests.cpp b/untests/vmath_qua_fun_tests.cpp index fc61a1c..b3baf6c 100644 --- a/untests/vmath_qua_fun_tests.cpp +++ b/untests/vmath_qua_fun_tests.cpp @@ -14,32 +14,6 @@ namespace } TEST_CASE("vmath/qua_fun") { - SUBCASE("Detail") { - STATIC_REQUIRE(map_join([](const int& x){ - return x * 2; - }, qua(1,2,3,4)) == qua(2,4,6,8)); - - STATIC_REQUIRE(map_join([](const int& x, const int& y){ - return x + y; - }, qua(1,2,3,4), qua(2,3,4,5)) == qua(3,5,7,9)); - - STATIC_REQUIRE(map_join([](const int& x, const int& y, const int& z){ - return x + y + z; - }, qua(1,2,3,4), qua(2,3,4,5), qua(3,4,5,6)) == qua(6,9,12,15)); - - STATIC_REQUIRE(fold_join([](int acc, const int& x){ - return acc + x; - }, 0, qua(1,2,3,4)) == 10); - - STATIC_REQUIRE(fold_join([](int acc, const int& x, const int& y){ - return acc + x + y; - }, 0, qua(1,2,3,4), qua(2,3,4,5)) == 24); - - STATIC_REQUIRE(fold1_join([](const int& acc, const int& x){ - return acc + x; - }, qua{1,2,3,4}) == 10); - } - SUBCASE("Operators") { STATIC_REQUIRE(+qua(1,-2,3,-4) == qua(1,-2,3,-4)); STATIC_REQUIRE(-qua(1,-2,3,-4) == qua(-1,2,-3,4)); diff --git a/untests/vmath_qua_tests.cpp b/untests/vmath_qua_tests.cpp index 8456053..d67d1dc 100644 --- a/untests/vmath_qua_tests.cpp +++ b/untests/vmath_qua_tests.cpp @@ -23,35 +23,26 @@ TEST_CASE("vmath/qua") { } SUBCASE("guides") { - STATIC_REQUIRE(qua{1}.size == 4); STATIC_REQUIRE(qua{1,2,3,4}.size == 4); STATIC_REQUIRE(qua{{1,2,3},4}.size == 4); STATIC_REQUIRE(qua{vec{1,2,3},4}.size == 4); STATIC_REQUIRE(qua{{1,2,3,4}}.size == 4); - STATIC_REQUIRE(qua{vec{1,2,3,4}}.size == 4); + STATIC_REQUIRE(qua(vec{1,2,3,4}).size == 4); } SUBCASE("ctors") { { - STATIC_REQUIRE(fqua{}.x == 0.f); - STATIC_REQUIRE(fqua{}.y == 0.f); - STATIC_REQUIRE(fqua{}.z == 0.f); - STATIC_REQUIRE(fqua{}.w == 1.f); + STATIC_REQUIRE(fqua{}.v == uapprox3(0.f)); + STATIC_REQUIRE(fqua{}.s == uapprox(1.f)); - STATIC_REQUIRE(fqua{1,2,3,4}.x == 1.f); - STATIC_REQUIRE(fqua{1,2,3,4}.y == 2.f); - STATIC_REQUIRE(fqua{1,2,3,4}.z == 3.f); - STATIC_REQUIRE(fqua{1,2,3,4}.w == 4.f); + STATIC_REQUIRE(fqua{1,2,3,4}.v == uapprox3(1.f,2.f,3.f)); + STATIC_REQUIRE(fqua{1,2,3,4}.s == uapprox(4.f)); - STATIC_REQUIRE(fqua{{1,2,3},4}.x == 1.f); - STATIC_REQUIRE(fqua{{1,2,3},4}.y == 2.f); - STATIC_REQUIRE(fqua{{1,2,3},4}.z == 3.f); - STATIC_REQUIRE(fqua{{1,2,3},4}.w == 4.f); + STATIC_REQUIRE(fqua{{1,2,3},4}.v == uapprox3(1.f,2.f,3.f)); + STATIC_REQUIRE(fqua{{1,2,3},4}.s == uapprox(4.f)); - STATIC_REQUIRE(fqua{{1,2,3,4}}.x == 1.f); - STATIC_REQUIRE(fqua{{1,2,3,4}}.y == 2.f); - STATIC_REQUIRE(fqua{{1,2,3,4}}.z == 3.f); - STATIC_REQUIRE(fqua{{1,2,3,4}}.w == 4.f); + STATIC_REQUIRE(fqua{{1,2,3,4}}.v == uapprox3(1.f,2.f,3.f)); + STATIC_REQUIRE(fqua{{1,2,3,4}}.s == uapprox(4.f)); } { constexpr fqua q(1,2,3,4); @@ -64,9 +55,9 @@ TEST_CASE("vmath/qua") { STATIC_REQUIRE(q2 == fqua(1,2,3,4)); } { - STATIC_REQUIRE(fqua(2) == fqua(0,0,0,2)); STATIC_REQUIRE(fqua(1,2,3,4) == fqua(1,2,3,4)); STATIC_REQUIRE(fqua(float3(1,2,3),4) == fqua(1,2,3,4)); + STATIC_REQUIRE(fqua(float4(1,2,3,4)) == fqua(1,2,3,4)); } } @@ -185,24 +176,20 @@ TEST_CASE("vmath/qua") { SUBCASE("operator[]") { { - STATIC_REQUIRE(fqua(1,2,3,4).x == 1); - STATIC_REQUIRE(fqua(1,2,3,4).y == 2); - STATIC_REQUIRE(fqua(1,2,3,4).z == 3); - STATIC_REQUIRE(fqua(1,2,3,4).w == 4); + STATIC_REQUIRE(qua(1,2,3,4).v == vec(1,2,3)); + STATIC_REQUIRE(qua(1,2,3,4).s == 4); } { - STATIC_REQUIRE(fqua(1,2,3,4)[0] == 1); - STATIC_REQUIRE(fqua(1,2,3,4)[1] == 2); - STATIC_REQUIRE(fqua(1,2,3,4)[2] == 3); - STATIC_REQUIRE(fqua(1,2,3,4)[3] == 4); + STATIC_REQUIRE(qua(1,2,3,4)[0] == 1); + STATIC_REQUIRE(qua(1,2,3,4)[1] == 2); + STATIC_REQUIRE(qua(1,2,3,4)[2] == 3); + STATIC_REQUIRE(qua(1,2,3,4)[3] == 4); } { - fqua v; - v.x = 1; - v.y = 2; - v.z = 3; - v.w = 4; - REQUIRE(v == fqua(1,2,3,4)); + qua v; + v.v = vec(1,2,3); + v.s = 4; + REQUIRE(v == qua(1,2,3,4)); } }