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") {