diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index 3bb07a3..c25d1e3 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -15,14 +15,14 @@ namespace vmath_hpp { template < typename T > - [[nodiscard]] constexpr std::enable_if_t, T> - radians(T degrees) noexcept { + [[nodiscard]] std::enable_if_t, T> + constexpr radians(T degrees) noexcept { return degrees * T(0.01745329251994329576923690768489); } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, T> - degrees(T radians) noexcept { + [[nodiscard]] std::enable_if_t, T> + constexpr degrees(T radians) noexcept { return radians * T(57.295779513082320876798154814105); } @@ -178,6 +178,12 @@ namespace vmath_hpp return static_cast((T(0) < x) - (x < T(0))); } + template < typename T > + [[nodiscard]] std::enable_if_t, T> + constexpr reciprocal(T x) noexcept { + return T(1) / x; + } + template < typename T > [[nodiscard]] std::enable_if_t, T> floor(T x) noexcept { @@ -293,32 +299,32 @@ namespace vmath_hpp namespace vmath_hpp { template < typename T > - [[nodiscard]] constexpr std::enable_if_t, T> - dot(T x, T y) noexcept { + [[nodiscard]] std::enable_if_t, T> + constexpr dot(T x, T y) noexcept { return x * y; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, T> - length(T x) noexcept { + [[nodiscard]] std::enable_if_t, T> + constexpr length(T x) noexcept { return abs(x); } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, T> - length2(T x) noexcept { + [[nodiscard]] std::enable_if_t, T> + constexpr length2(T x) noexcept { return dot(x, x); } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, T> - distance(T x, T y) noexcept { + [[nodiscard]] std::enable_if_t, T> + constexpr distance(T x, T y) noexcept { return length(y - x); } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, T> - distance2(T x, T y) noexcept { + [[nodiscard]] std::enable_if_t, T> + constexpr distance2(T x, T y) noexcept { return length2(y - x); } @@ -329,14 +335,14 @@ namespace vmath_hpp } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, T> - faceforward(T n, T i, T nref) noexcept { + [[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]] constexpr std::enable_if_t, T> - reflect(T i, T n) noexcept { + [[nodiscard]] std::enable_if_t, T> + constexpr reflect(T i, T n) noexcept { return i - n * dot(n, i) * T(2); } @@ -356,62 +362,62 @@ namespace vmath_hpp namespace vmath_hpp { template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - less(T x, T y) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr less(T x, T y) noexcept { return x < y; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - less_equal(T x, T y) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr less_equal(T x, T y) noexcept { return x <= y; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - greater(T x, T y) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr greater(T x, T y) noexcept { return x > y; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - greater_equal(T x, T y) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr greater_equal(T x, T y) noexcept { return x >= y; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - equal_to(T x, T y) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr equal_to(T x, T y) noexcept { return x == y; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - equal_to(T x, T y, T epsilon) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr equal_to(T x, T y, T epsilon) noexcept { return abs(x - y) <= epsilon; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - not_equal_to(T x, T y) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr not_equal_to(T x, T y) noexcept { return x != y; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - not_equal_to(T x, T y, T epsilon) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr not_equal_to(T x, T y, T epsilon) noexcept { return abs(x - y) > epsilon; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - any(T x) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr any(T x) noexcept { return !!x; } template < typename T > - [[nodiscard]] constexpr std::enable_if_t, bool> - all(T x) noexcept { + [[nodiscard]] std::enable_if_t, bool> + constexpr all(T x) noexcept { return !!x; } } diff --git a/headers/vmath.hpp/vmath_mat.hpp b/headers/vmath.hpp/vmath_mat.hpp index 004cb89..ee45b27 100644 --- a/headers/vmath.hpp/vmath_mat.hpp +++ b/headers/vmath.hpp/vmath_mat.hpp @@ -197,22 +197,22 @@ namespace vmath_hpp } } - constexpr reference operator[](std::size_t index) noexcept { + [[nodiscard]] constexpr reference operator[](std::size_t index) noexcept { return rows[index]; } - constexpr const_reference operator[](std::size_t index) const noexcept { + [[nodiscard]] constexpr const_reference operator[](std::size_t index) const noexcept { return rows[index]; } - constexpr reference at(std::size_t index) { + [[nodiscard]] constexpr reference at(std::size_t index) { if ( index >= Size ) { throw std::out_of_range("mat::at"); } return rows[index]; } - constexpr const_reference at(std::size_t index) const { + [[nodiscard]] constexpr const_reference at(std::size_t index) const { if ( index >= Size ) { throw std::out_of_range("mat::at"); } diff --git a/headers/vmath.hpp/vmath_mat_fun.hpp b/headers/vmath.hpp/vmath_mat_fun.hpp index 1039cb6..273295d 100644 --- a/headers/vmath.hpp/vmath_mat_fun.hpp +++ b/headers/vmath.hpp/vmath_mat_fun.hpp @@ -11,70 +11,86 @@ #include "vmath_fun.hpp" #include "vmath_mat.hpp" +#include "vmath_vec.hpp" +#include "vmath_vec_fun.hpp" + namespace vmath_hpp::detail { namespace impl { template < typename A, std::size_t Size, typename F, std::size_t... Is > - constexpr auto map_impl(F&& f, const mat& a, std::index_sequence) + [[nodiscard]] constexpr auto map_impl(F&& f, const mat& a, std::index_sequence) -> mat>::value_type, Size> { return { f(a[Is])... }; } template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > - constexpr auto zip_impl(F&& f, const mat& a, const mat& b, std::index_sequence) + [[nodiscard]] constexpr auto zip_impl(F&& f, const mat& a, const mat& b, std::index_sequence) -> mat, vec>::value_type, Size> { return { f(a[Is], b[Is])... }; } template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is > - constexpr auto zip_impl(F&& f, const mat& a, const mat& b, const mat& c, std::index_sequence) + [[nodiscard]] constexpr auto zip_impl(F&& f, const mat& a, const mat& b, const mat& c, std::index_sequence) -> mat, vec, vec>::value_type, Size> { return { f(a[Is], b[Is], c[Is])... }; } template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > - constexpr auto fold_impl(F&& f, A init, const mat& b, std::index_sequence) - -> A - { + [[nodiscard]] constexpr A fold_impl(F&& f, A init, const mat& b, 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 > - constexpr auto fold_impl(F&& f, A init, const mat& b, const mat& c, std::index_sequence) - -> A - { + [[nodiscard]] constexpr A fold_impl(F&& f, A init, const mat& b, const mat& c, 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 vec fold1_impl(F&& f, const mat& a, std::index_sequence) { + vec init = a[I]; + return ((init = f(std::move(init), a[Is])), ...); + } } template < typename A, std::size_t Size, typename F > - constexpr auto map(F&& f, const mat& a) { + [[nodiscard]] constexpr auto map(F&& f, const mat& a) + -> mat>::value_type, Size> + { return impl::map_impl(std::forward(f), a, std::make_index_sequence{}); } template < typename A, typename B, std::size_t Size, typename F > - constexpr auto zip(F&& f, const mat& a, const mat& b) { + [[nodiscard]] constexpr auto zip(F&& f, const mat& a, const mat& b) + -> mat, vec>::value_type, Size> + { return impl::zip_impl(std::forward(f), a, b, std::make_index_sequence{}); } template < typename A, typename B, typename C, std::size_t Size, typename F > - constexpr auto zip(F&& f, const mat& a, const mat& b, const mat& c) { + [[nodiscard]] constexpr auto zip(F&& f, const mat& a, const mat& b, const mat& c) + -> mat, vec, vec>::value_type, Size> + { return impl::zip_impl(std::forward(f), a, b, c, std::make_index_sequence{}); } template < typename A, typename B, std::size_t Size, typename F > - constexpr auto fold(F&& f, A init, const mat& b) { + [[nodiscard]] constexpr A fold(F&& f, A init, const mat& b) { return impl::fold_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 > - constexpr auto fold(F&& f, A init, const mat& b, const mat& c) { + [[nodiscard]] constexpr A fold(F&& f, A init, const mat& b, const mat& c) { return impl::fold_impl(std::forward(f), std::move(init), b, c, std::make_index_sequence{}); } + + template < typename A, std::size_t Size, typename F > + [[nodiscard]] constexpr vec fold1(F&& f, const mat& a) { + return impl::fold1_impl(std::forward(f), a, std::make_index_sequence{}); + } } // @@ -86,24 +102,24 @@ namespace vmath_hpp // -operator template < typename T, std::size_t Size > - constexpr mat operator-(const mat& xs) { + [[nodiscard]] constexpr mat operator-(const mat& xs) { return map(std::negate<>(), xs); } // operator+ template < typename T, std::size_t Size > - constexpr mat operator+(const mat& xs, T y) { + [[nodiscard]] constexpr mat operator+(const mat& xs, T y) { return map([y](const vec& x){ return x + y; }, xs); } template < typename T, std::size_t Size > - constexpr mat operator+(T x, const mat& ys) { + [[nodiscard]] constexpr mat operator+(T x, const mat& ys) { return map([x](const vec& y){ return x + y; }, ys); } template < typename T, std::size_t Size > - constexpr mat operator+(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr mat operator+(const mat& xs, const mat& ys) { return zip(std::plus<>(), xs, ys); } @@ -122,17 +138,17 @@ namespace vmath_hpp // operator- template < typename T, std::size_t Size > - constexpr mat operator-(const mat& xs, T y) { + [[nodiscard]] constexpr mat operator-(const mat& xs, T y) { return map([y](const vec& x){ return x - y; }, xs); } template < typename T, std::size_t Size > - constexpr mat operator-(T x, const mat& ys) { + [[nodiscard]] constexpr mat operator-(T x, const mat& ys) { return map([x](const vec& y){ return x - y; }, ys); } template < typename T, std::size_t Size > - constexpr mat operator-(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr mat operator-(const mat& xs, const mat& ys) { return zip(std::minus<>(), xs, ys); } @@ -151,24 +167,24 @@ namespace vmath_hpp // operator* template < typename T, std::size_t Size > - constexpr mat operator*(const mat& xs, T y) { + [[nodiscard]] constexpr mat operator*(const mat& xs, T y) { return map([y](const vec& x){ return x * y; }, xs); } template < typename T, std::size_t Size > - constexpr mat operator*(T x, const mat& ys) { + [[nodiscard]] constexpr mat operator*(T x, const mat& ys) { return map([x](const vec& y){ return x * y; }, ys); } template < typename T > - constexpr vec operator*(const vec& xs, const mat& ys) { + [[nodiscard]] constexpr vec operator*(const vec& xs, const mat& ys) { return { xs.x * ys[0][0] + xs.y * ys[1][0], xs.x * ys[0][1] + xs.y * ys[1][1]}; } template < typename T > - constexpr mat operator*(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr mat operator*(const mat& xs, const mat& ys) { return { xs[0][0] * ys[0][0] + xs[0][1] * ys[1][0], xs[0][0] * ys[0][1] + xs[0][1] * ys[1][1], @@ -178,7 +194,7 @@ namespace vmath_hpp } template < typename T > - constexpr vec operator*(const vec& xs, const mat& ys) { + [[nodiscard]] constexpr vec operator*(const vec& xs, const mat& ys) { return { xs.x * ys[0][0] + xs.y * ys[1][0] + xs.z * ys[2][0], xs.x * ys[0][1] + xs.y * ys[1][1] + xs.z * ys[2][1], @@ -186,7 +202,7 @@ namespace vmath_hpp } template < typename T > - constexpr mat operator*(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr mat operator*(const mat& xs, const mat& ys) { return { xs[0][0] * ys[0][0] + xs[0][1] * ys[1][0] + xs[0][2] * ys[2][0], xs[0][0] * ys[0][1] + xs[0][1] * ys[1][1] + xs[0][2] * ys[2][1], @@ -202,7 +218,7 @@ namespace vmath_hpp } template < typename T > - constexpr vec operator*(const vec& xs, const mat& ys) { + [[nodiscard]] constexpr vec operator*(const vec& xs, const mat& ys) { return { xs.x * ys[0][0] + xs.y * ys[1][0] + xs.z * ys[2][0] + xs.w * ys[3][0], xs.x * ys[0][1] + xs.y * ys[1][1] + xs.z * ys[2][1] + xs.w * ys[3][1], @@ -211,7 +227,7 @@ namespace vmath_hpp } template < typename T > - constexpr mat operator*(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr mat operator*(const mat& xs, const mat& ys) { return { xs[0][0] * ys[0][0] + xs[0][1] * ys[1][0] + xs[0][2] * ys[2][0] + xs[0][3] * ys[3][0], xs[0][0] * ys[0][1] + xs[0][1] * ys[1][1] + xs[0][2] * ys[2][1] + xs[0][3] * ys[3][1], @@ -254,17 +270,17 @@ namespace vmath_hpp // operator/ template < typename T, std::size_t Size > - constexpr mat operator/(const mat& xs, T y) { + [[nodiscard]] constexpr mat operator/(const mat& xs, T y) { return map([y](const vec& x){ return x / y; }, xs); } template < typename T, std::size_t Size > - constexpr mat operator/(T x, const mat& ys) { + [[nodiscard]] constexpr mat operator/(T x, const mat& ys) { return map([x](const vec& y){ return x / y; }, ys); } template < typename T, std::size_t Size > - constexpr mat operator/(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr mat operator/(const mat& xs, const mat& ys) { return zip(std::divides<>(), xs, ys); } @@ -283,14 +299,14 @@ namespace vmath_hpp // operator== template < typename T, std::size_t Size > - constexpr bool operator==(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr bool operator==(const mat& xs, const mat& ys) { return fold([](bool acc, const vec& x, const vec& y){ return acc && (x == y); }, true, xs, ys); } template < typename T, std::size_t Size > - constexpr bool operator!=(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr bool operator!=(const mat& xs, const mat& ys) { return fold([](bool acc, const vec& x, const vec& y){ return acc || (x != y); }, false, xs, ys); @@ -299,7 +315,7 @@ namespace vmath_hpp // operator< template < typename T, std::size_t Size > - constexpr bool operator<(const mat& xs, const mat& ys) { + [[nodiscard]] constexpr bool operator<(const mat& xs, const mat& ys) { for ( std::size_t i = 0; i < Size; ++i ) { if ( xs[i] < ys[i] ) { return true; @@ -321,7 +337,7 @@ namespace vmath_hpp namespace impl { template < typename T > - constexpr mat transpose_2x2_impl( + [[nodiscard]] constexpr mat transpose_2x2_impl( T a, T c, T b, T d) { @@ -331,7 +347,7 @@ namespace vmath_hpp } template < typename T > - constexpr mat transpose_3x3_impl( + [[nodiscard]] constexpr mat transpose_3x3_impl( T a, T d, T g, T b, T e, T h, T c, T f, T i) @@ -343,7 +359,7 @@ namespace vmath_hpp } template < typename T > - constexpr mat transpose_4x4_impl( + [[nodiscard]] constexpr mat transpose_4x4_impl( T a, T e, T i, T m, T b, T f, T j, T n, T c, T g, T k, T o, @@ -358,14 +374,14 @@ namespace vmath_hpp } template < typename T > - constexpr mat transpose(const mat& m) { + [[nodiscard]] constexpr mat transpose(const mat& m) { return impl::transpose_2x2_impl( m[0][0], m[0][1], m[1][0], m[1][1]); } template < typename T > - constexpr mat transpose(const mat& m) { + [[nodiscard]] constexpr mat transpose(const mat& m) { return impl::transpose_3x3_impl( m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], @@ -373,7 +389,7 @@ namespace vmath_hpp } template < typename T > - constexpr mat transpose(const mat& m) { + [[nodiscard]] constexpr mat transpose(const mat& m) { return impl::transpose_4x4_impl( m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], @@ -384,7 +400,7 @@ namespace vmath_hpp namespace impl { template < typename T > - constexpr T determinant_2x2_impl( + [[nodiscard]] constexpr T determinant_2x2_impl( T a, T b, T c, T d) { @@ -394,7 +410,7 @@ namespace vmath_hpp } template < typename T > - constexpr T determinant_3x3_impl( + [[nodiscard]] constexpr T determinant_3x3_impl( T a, T b, T c, T d, T e, T f, T g, T h, T i) @@ -407,7 +423,7 @@ namespace vmath_hpp } template < typename T > - constexpr T determinant_4x4_impl( + [[nodiscard]] constexpr T determinant_4x4_impl( T a, T b, T c, T d, T e, T f, T g, T h, T i, T j, T k, T l, @@ -422,14 +438,14 @@ namespace vmath_hpp } template < typename T > - constexpr T determinant(const mat& m) { + [[nodiscard]] constexpr T determinant(const mat& m) { return impl::determinant_2x2_impl( m[0][0], m[0][1], m[1][0], m[1][1]); } template < typename T > - constexpr T determinant(const mat& m) { + [[nodiscard]] constexpr T determinant(const mat& m) { return impl::determinant_3x3_impl( m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], @@ -437,7 +453,7 @@ namespace vmath_hpp } template < typename T > - constexpr T determinant(const mat& m) { + [[nodiscard]] constexpr T determinant(const mat& m) { return impl::determinant_4x4_impl( m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], @@ -448,13 +464,13 @@ namespace vmath_hpp namespace impl { template < typename T > - constexpr mat inverse_2x2_impl( + [[nodiscard]] constexpr mat inverse_2x2_impl( T a, T b, T c, T d) { - const T inv_det = T(1) / determinant_2x2_impl( + const T inv_det = reciprocal(determinant_2x2_impl( a, b, - c, d); + c, d)); const mat inv_m( d, -b, @@ -464,15 +480,15 @@ namespace vmath_hpp } template < typename T > - constexpr mat inverse_3x3_impl( + [[nodiscard]] constexpr mat inverse_3x3_impl( T a, T b, T c, T d, T e, T f, T g, T h, T i) { - const T inv_det = T(1) / determinant_3x3_impl( + const T inv_det = reciprocal(determinant_3x3_impl( a, b, c, d, e, f, - g, h, i); + g, h, i)); const mat inv_m( e * i - f * h, @@ -489,17 +505,17 @@ namespace vmath_hpp } template < typename T > - constexpr mat inverse_4x4_impl( + [[nodiscard]] constexpr mat inverse_4x4_impl( T a, T b, T c, T d, T e, T f, T g, T h, T i, T j, T k, T l, T m, T n, T o, T p) { - const T inv_det = T(1) / determinant_4x4_impl( + const T inv_det = reciprocal(determinant_4x4_impl( a, b, c, d, e, f, g, h, i, j, k, l, - m, n, o, p); + m, n, o, p)); const mat inv_m( (f * (k * p - l * o) + g * (l * n - j * p) + h * (j * o - k * n)), @@ -524,14 +540,14 @@ namespace vmath_hpp } template < typename T > - constexpr mat inverse(const mat& m) { + [[nodiscard]] constexpr mat inverse(const mat& m) { return impl::inverse_2x2_impl( m[0][0], m[0][1], m[1][0], m[1][1]); } template < typename T > - constexpr matinverse(const mat& m) { + [[nodiscard]] constexpr mat inverse(const mat& m) { return impl::inverse_3x3_impl( m[0][0], m[0][1], m[0][2], m[1][0], m[1][1], m[1][2], @@ -539,7 +555,7 @@ namespace vmath_hpp } template < typename T > - constexpr matinverse(const mat& m) { + [[nodiscard]] constexpr mat inverse(const mat& m) { return impl::inverse_4x4_impl( m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], diff --git a/headers/vmath.hpp/vmath_vec.hpp b/headers/vmath.hpp/vmath_vec.hpp index 5f14307..cd80289 100644 --- a/headers/vmath.hpp/vmath_vec.hpp +++ b/headers/vmath.hpp/vmath_vec.hpp @@ -32,7 +32,7 @@ namespace vmath_hpp::detail constexpr explicit vec_base(const vec_base& xy) : x{xy[0]}, y{xy[1]} {} - constexpr T& operator[](std::size_t index) noexcept { + [[nodiscard]] constexpr T& operator[](std::size_t index) noexcept { switch ( index ) { default: case 0: return x; @@ -40,7 +40,7 @@ namespace vmath_hpp::detail } } - constexpr const T& operator[](std::size_t index) const noexcept { + [[nodiscard]] constexpr const T& operator[](std::size_t index) const noexcept { switch ( index ) { default: case 0: return x; @@ -71,7 +71,7 @@ namespace vmath_hpp::detail constexpr explicit vec_base(const vec_base& xyz) : x{xyz[0]}, y{xyz[1]}, z{xyz[2]} {} - constexpr T& operator[](std::size_t index) noexcept { + [[nodiscard]] constexpr T& operator[](std::size_t index) noexcept { switch ( index ) { default: case 0: return x; @@ -80,7 +80,7 @@ namespace vmath_hpp::detail } } - constexpr const T& operator[](std::size_t index) const noexcept { + [[nodiscard]] constexpr const T& operator[](std::size_t index) const noexcept { switch ( index ) { default: case 0: return x; @@ -121,7 +121,7 @@ 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 T& operator[](std::size_t index) noexcept { + [[nodiscard]] constexpr T& operator[](std::size_t index) noexcept { switch ( index ) { default: case 0: return x; @@ -131,7 +131,7 @@ namespace vmath_hpp::detail } } - constexpr const T& operator[](std::size_t index) const noexcept { + [[nodiscard]] constexpr const T& operator[](std::size_t index) const noexcept { switch ( index ) { default: case 0: return x; @@ -179,14 +179,14 @@ namespace vmath_hpp } } - constexpr reference at(std::size_t index) { + [[nodiscard]] constexpr reference at(std::size_t index) { if ( index >= Size ) { throw std::out_of_range("vec::at"); } return (*this)[index]; } - constexpr const_reference at(std::size_t index) const { + [[nodiscard]] constexpr const_reference at(std::size_t index) const { if ( index >= Size ) { throw std::out_of_range("vec::at"); } diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index fe28c40..8efb19e 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -16,76 +16,76 @@ namespace vmath_hpp::detail namespace impl { template < typename A, std::size_t Size, typename F, std::size_t... Is > - constexpr auto map_impl(F&& f, const vec& a, std::index_sequence) + [[nodiscard]] constexpr auto map_impl(F&& f, const vec& a, std::index_sequence) -> vec, Size> { return { f(a[Is])... }; } template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > - constexpr auto zip_impl(F&& f, const vec& a, const vec& b, std::index_sequence) + [[nodiscard]] constexpr auto zip_impl(F&& f, const vec& a, const vec& b, std::index_sequence) -> vec, Size> { return { f(a[Is], b[Is])... }; } template < typename A, typename B, typename C, std::size_t Size, typename F, std::size_t... Is > - constexpr auto zip_impl(F&& f, const vec& a, const vec& b, const vec& c, std::index_sequence) + [[nodiscard]] constexpr auto zip_impl(F&& f, const vec& a, const vec& b, const vec& c, std::index_sequence) -> vec, Size> { return { f(a[Is], b[Is], c[Is])... }; } template < typename A, typename B, std::size_t Size, typename F, std::size_t... Is > - constexpr auto fold_impl(F&& f, A init, const vec& b, std::index_sequence) - -> A - { + [[nodiscard]] constexpr A fold_impl(F&& f, A init, const vec& b, 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 > - constexpr auto fold_impl(F&& f, A init, const vec& b, const vec& c, std::index_sequence) - -> A - { + [[nodiscard]] constexpr A fold_impl(F&& f, A init, const vec& b, const vec& c, 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 > - constexpr auto fold1_impl(F&& f, const vec& a, std::index_sequence) - -> A - { + [[nodiscard]] constexpr A fold1_impl(F&& f, const vec& a, std::index_sequence) { A init = a[I]; return ((init = f(std::move(init), a[Is])), ...); } } template < typename A, std::size_t Size, typename F > - constexpr auto map(F&& f, const vec& a) { + [[nodiscard]] constexpr auto map(F&& f, const vec& a) + -> vec, Size> + { return impl::map_impl(std::forward(f), a, std::make_index_sequence{}); } template < typename A, typename B, std::size_t Size, typename F > - constexpr auto zip(F&& f, const vec& a, const vec& b) { + [[nodiscard]] constexpr auto zip(F&& f, const vec& a, const vec& b) + -> vec, Size> + { return impl::zip_impl(std::forward(f), a, b, std::make_index_sequence{}); } template < typename A, typename B, typename C, std::size_t Size, typename F > - constexpr auto zip(F&& f, const vec& a, const vec& b, const vec& c) { + [[nodiscard]] constexpr auto zip(F&& f, const vec& a, const vec& b, const vec& c) + -> vec, Size> + { return impl::zip_impl(std::forward(f), a, b, c, std::make_index_sequence{}); } template < typename A, typename B, std::size_t Size, typename F > - constexpr auto fold(F&& f, A init, const vec& b) { + [[nodiscard]] constexpr A fold(F&& f, A init, const vec& b) { return impl::fold_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 > - constexpr auto fold(F&& f, A init, const vec& b, const vec& c) { + [[nodiscard]] constexpr A fold(F&& f, A init, const vec& b, const vec& c) { return impl::fold_impl(std::forward(f), std::move(init), b, c, std::make_index_sequence{}); } template < typename A, std::size_t Size, typename F > - constexpr auto fold1(F&& f, const vec& a) { + [[nodiscard]] constexpr A fold1(F&& f, const vec& a) { return impl::fold1_impl(std::forward(f), a, std::make_index_sequence{}); } } @@ -99,24 +99,24 @@ namespace vmath_hpp // -operator template < typename T, std::size_t Size > - constexpr vec operator-(const vec& xs) { + [[nodiscard]] constexpr vec operator-(const vec& xs) { return map(std::negate<>(), xs); } // operator+ template < typename T, std::size_t Size > - constexpr vec operator+(const vec& xs, T y) { + [[nodiscard]] constexpr vec operator+(const vec& xs, T y) { return map([y](T x){ return x + y; }, xs); } template < typename T, std::size_t Size > - constexpr vec operator+(T x, const vec& ys) { + [[nodiscard]] constexpr vec operator+(T x, const vec& ys) { return map([x](T y){ return x + y; }, ys); } template < typename T, std::size_t Size > - constexpr vec operator+(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec operator+(const vec& xs, const vec& ys) { return zip(std::plus<>(), xs, ys); } @@ -135,17 +135,17 @@ namespace vmath_hpp // operator- template < typename T, std::size_t Size > - constexpr vec operator-(const vec& xs, T y) { + [[nodiscard]] constexpr vec operator-(const vec& xs, T y) { return map([y](T x){ return x - y; }, xs); } template < typename T, std::size_t Size > - constexpr vec operator-(T x, const vec& ys) { + [[nodiscard]] constexpr vec operator-(T x, const vec& ys) { return map([x](T y){ return x - y; }, ys); } template < typename T, std::size_t Size > - constexpr vec operator-(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec operator-(const vec& xs, const vec& ys) { return zip(std::minus<>(), xs, ys); } @@ -164,17 +164,17 @@ namespace vmath_hpp // operator* template < typename T, std::size_t Size > - constexpr vec operator*(const vec& xs, T y) { + [[nodiscard]] constexpr vec operator*(const vec& xs, T y) { return map([y](T x){ return x * y; }, xs); } template < typename T, std::size_t Size > - constexpr vec operator*(T x, const vec& ys) { + [[nodiscard]] constexpr vec operator*(T x, const vec& ys) { return map([x](T y){ return x * y; }, ys); } template < typename T, std::size_t Size > - constexpr vec operator*(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec operator*(const vec& xs, const vec& ys) { return zip(std::multiplies<>(), xs, ys); } @@ -193,17 +193,17 @@ namespace vmath_hpp // operator/ template < typename T, std::size_t Size > - constexpr vec operator/(const vec& xs, T y) { + [[nodiscard]] constexpr vec operator/(const vec& xs, T y) { return map([y](T x){ return x / y; }, xs); } template < typename T, std::size_t Size > - constexpr vec operator/(T x, const vec& ys) { + [[nodiscard]] constexpr vec operator/(T x, const vec& ys) { return map([x](T y){ return x / y; }, ys); } template < typename T, std::size_t Size > - constexpr vec operator/(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec operator/(const vec& xs, const vec& ys) { return zip(std::divides<>(), xs, ys); } @@ -222,14 +222,14 @@ namespace vmath_hpp // operator== template < typename T, std::size_t Size > - constexpr bool operator==(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr bool operator==(const vec& xs, const vec& ys) { return fold([](bool acc, T x, T y){ return acc && (x == y); }, true, xs, ys); } template < typename T, std::size_t Size > - constexpr bool operator!=(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr bool operator!=(const vec& xs, const vec& ys) { return fold([](bool acc, T x, T y){ return acc || (x != y); }, false, xs, ys); @@ -238,7 +238,7 @@ namespace vmath_hpp // operator< template < typename T, std::size_t Size > - constexpr bool operator<(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr bool operator<(const vec& xs, const vec& ys) { for ( std::size_t i = 0; i < Size; ++i ) { if ( xs[i] < ys[i] ) { return true; @@ -258,77 +258,77 @@ namespace vmath_hpp namespace vmath_hpp { template < typename T, std::size_t Size > - constexpr vec radians(const vec& degrees) { + [[nodiscard]] constexpr vec radians(const vec& degrees) { return map([](T x) { return radians(x); }, degrees); } template < typename T, std::size_t Size > - constexpr vec degrees(const vec& radians) { + [[nodiscard]] constexpr vec degrees(const vec& radians) { return map([](T x) { return degrees(x); }, radians); } template < typename T, std::size_t Size > - vec sin(const vec& xs) { + [[nodiscard]] vec sin(const vec& xs) { return map([](T x) { return sin(x); }, xs); } template < typename T, std::size_t Size > - vec cos(const vec& xs) { + [[nodiscard]] vec cos(const vec& xs) { return map([](T x) { return cos(x); }, xs); } template < typename T, std::size_t Size > - vec tan(const vec& xs) { + [[nodiscard]] vec tan(const vec& xs) { return map([](T x) { return tan(x); }, xs); } template < typename T, std::size_t Size > - vec asin(const vec& xs) { + [[nodiscard]] vec asin(const vec& xs) { return map([](T x) { return asin(x); }, xs); } template < typename T, std::size_t Size > - vec acos(const vec& xs) { + [[nodiscard]] vec acos(const vec& xs) { return map([](T x) { return acos(x); }, xs); } template < typename T, std::size_t Size > - vec atan(const vec& xs) { + [[nodiscard]] vec atan(const vec& xs) { return map([](T x) { return atan(x); }, xs); } template < typename T, std::size_t Size > - vec atan2(const vec& ys, const vec& xs) { + [[nodiscard]] vec atan2(const vec& ys, const vec& xs) { return zip([](T y, T x) { return atan2(y, x); }, ys, xs); } template < typename T, std::size_t Size > - vec sinh(const vec& xs) { + [[nodiscard]] vec sinh(const vec& xs) { return map([](T x) { return sinh(x); }, xs); } template < typename T, std::size_t Size > - vec cosh(const vec& xs) { + [[nodiscard]] vec cosh(const vec& xs) { return map([](T x) { return cosh(x); }, xs); } template < typename T, std::size_t Size > - vec tanh(const vec& xs) { + [[nodiscard]] vec tanh(const vec& xs) { return map([](T x) { return tanh(x); }, xs); } template < typename T, std::size_t Size > - vec asinh(const vec& xs) { + [[nodiscard]] vec asinh(const vec& xs) { return map([](T x) { return asinh(x); }, xs); } template < typename T, std::size_t Size > - vec acosh(const vec& xs) { + [[nodiscard]] vec acosh(const vec& xs) { return map([](T x) { return acosh(x); }, xs); } template < typename T, std::size_t Size > - vec atanh(const vec& xs) { + [[nodiscard]] vec atanh(const vec& xs) { return map([](T x) { return atanh(x); }, xs); } } @@ -340,37 +340,37 @@ namespace vmath_hpp namespace vmath_hpp { template < typename T, std::size_t Size > - vec pow(const vec& xs, const vec& ys) { + [[nodiscard]] vec pow(const vec& xs, const vec& ys) { return zip([](T x, T y) { return pow(x, y); }, xs, ys); } template < typename T, std::size_t Size > - vec exp(const vec& xs) { + [[nodiscard]] vec exp(const vec& xs) { return map([](T x) { return exp(x); }, xs); } template < typename T, std::size_t Size > - vec log(const vec& xs) { + [[nodiscard]] vec log(const vec& xs) { return map([](T x) { return log(x); }, xs); } template < typename T, std::size_t Size > - vec exp2(const vec& xs) { + [[nodiscard]] vec exp2(const vec& xs) { return map([](T x) { return exp2(x); }, xs); } template < typename T, std::size_t Size > - vec log2(const vec& xs) { + [[nodiscard]] vec log2(const vec& xs) { return map([](T x) { return log2(x); }, xs); } template < typename T, std::size_t Size > - vec sqrt(const vec& xs) { + [[nodiscard]] vec sqrt(const vec& xs) { return map([](T x) { return sqrt(x); }, xs); } template < typename T, std::size_t Size > - vec rsqrt(const vec& xs) { + [[nodiscard]] vec rsqrt(const vec& xs) { return map([](T x) { return rsqrt(x); }, xs); } } @@ -382,47 +382,47 @@ namespace vmath_hpp namespace vmath_hpp { template < typename T, std::size_t Size > - vec abs(const vec& xs) { + [[nodiscard]] constexpr vec abs(const vec& xs) { return map([](T x) { return abs(x); }, xs); } template < typename T, std::size_t Size > - vec sign(const vec& xs) { + [[nodiscard]] constexpr vec sign(const vec& xs) { return map([](T x) { return sign(x); }, xs); } template < typename T, std::size_t Size > - vec floor(const vec& xs) { + [[nodiscard]] vec floor(const vec& xs) { return map([](T x) { return floor(x); }, xs); } template < typename T, std::size_t Size > - vec trunc(const vec& xs) { + [[nodiscard]] vec trunc(const vec& xs) { return map([](T x) { return trunc(x); }, xs); } template < typename T, std::size_t Size > - vec round(const vec& xs) { + [[nodiscard]] vec round(const vec& xs) { return map([](T x) { return round(x); }, xs); } template < typename T, std::size_t Size > - vec ceil(const vec& xs) { + [[nodiscard]] vec ceil(const vec& xs) { return map([](T x) { return ceil(x); }, xs); } template < typename T, std::size_t Size > - vec fract(const vec& xs) { + [[nodiscard]] vec fract(const vec& xs) { return map([](T x) { return fract(x); }, xs); } template < typename T, std::size_t Size > - vec fmod(const vec& xs, T y) { + [[nodiscard]] vec fmod(const vec& xs, T y) { return map([y](T x) { return fmod(x, y); }, xs); } template < typename T, std::size_t Size > - vec fmod(const vec& xs, const vec& ys) { + [[nodiscard]] vec fmod(const vec& xs, const vec& ys) { return zip([](T x, T y) { return fmod(x, y); }, xs, ys); } @@ -440,97 +440,97 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - constexpr T min(const vec& xs) { + [[nodiscard]] constexpr T min(const vec& xs) { return fold1([](T acc, T x){ return min(acc, x); }, xs); } template < typename T, std::size_t Size > - constexpr vec min(const vec& xs, T y) { + [[nodiscard]] constexpr vec min(const vec& xs, T y) { return map([y](T x) { return min(x, y); }, xs); } template < typename T, std::size_t Size > - constexpr vec min(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec min(const vec& xs, const vec& ys) { return zip([](T x, T y) { return min(x, y); }, xs, ys); } template < typename T, std::size_t Size > - constexpr T max(const vec& xs) { + [[nodiscard]] constexpr T max(const vec& xs) { return fold1([](T acc, T x){ return max(acc, x); }, xs); } template < typename T, std::size_t Size > - constexpr vec max(const vec& xs, T y) { + [[nodiscard]] constexpr vec max(const vec& xs, T y) { return map([y](T x) { return max(x, y); }, xs); } template < typename T, std::size_t Size > - constexpr vec max(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec max(const vec& xs, const vec& ys) { return zip([](T x, T y) { return max(x, y); }, xs, ys); } template < typename T, std::size_t Size > - constexpr vec clamp(const vec& xs, T min_x, T max_x) { + [[nodiscard]] constexpr vec clamp(const vec& xs, T min_x, T max_x) { return map([min_x, max_x](T x) { return clamp(x, min_x, max_x); }, xs); } template < typename T, std::size_t Size > - constexpr vec clamp(const vec& xs, const vec& min_xs, const vec& max_xs) { + [[nodiscard]] constexpr vec clamp(const vec& xs, const vec& min_xs, const vec& max_xs) { return zip([](T x, T min_x, T max_x) { return clamp(x, min_x, max_x); }, xs, min_xs, max_xs); } template < typename T, std::size_t Size > - constexpr vec saturate(const vec& xs) { + [[nodiscard]] constexpr vec saturate(const vec& xs) { return map([](T x) { return saturate(x); }, xs); } template < typename T, std::size_t Size > - constexpr vec lerp(const vec& xs, const vec& ys, T a) { + [[nodiscard]] constexpr vec lerp(const vec& xs, const vec& ys, T a) { return zip([a](T x, T y) { return lerp(x, y, a); }, xs, ys); } template < typename T, std::size_t Size > - constexpr vec lerp(const vec& xs, const vec& ys, const vec& as) { + [[nodiscard]] constexpr vec lerp(const vec& xs, const vec& ys, const vec& as) { return zip([](T x, T y, T a) { return lerp(x, y, a); }, xs, ys, as); } template < typename T, std::size_t Size > - constexpr vec step(T edge, const vec& xs) { + [[nodiscard]] constexpr vec step(T edge, const vec& xs) { return map([edge](T x) { return step(edge, x); }, xs); } template < typename T, std::size_t Size > - constexpr vec step(const vec& edges, const vec& xs) { + [[nodiscard]] constexpr vec step(const vec& edges, const vec& xs) { return zip([](T edge, T x) { return step(edge, x); }, edges, xs); } template < typename T, std::size_t Size > - constexpr vec smoothstep(T edge0, T edge1, const vec& xs) { + [[nodiscard]] constexpr vec smoothstep(T edge0, T edge1, const vec& xs) { return map([edge0, edge1](T x) { return smoothstep(edge0, edge1, x); }, xs); } template < typename T, std::size_t Size > - constexpr vec smoothstep(const vec& edges0, const vec& edges1, const vec& xs) { + [[nodiscard]] constexpr vec smoothstep(const vec& edges0, const vec& edges1, const vec& xs) { return zip([](T edge0, T edge1, T x) { return smoothstep(edge0, edge1, x); }, edges0, edges1, xs); } template < typename T, std::size_t Size > - vec isnan(const vec& xs) { + [[nodiscard]] vec isnan(const vec& xs) { return map([](T x) { return isnan(x); }, xs); } template < typename T, std::size_t Size > - vec isinf(const vec& xs) { + [[nodiscard]] vec isinf(const vec& xs) { return map([](T x) { return isinf(x); }, xs); } template < typename T, std::size_t Size > - vec isfinite(const vec& xs) { + [[nodiscard]] vec isfinite(const vec& xs) { return map([](T x) { return isfinite(x); }, xs); } template < typename T, std::size_t Size > - vec fma(const vec& as, const vec& bs, const vec& cs) { + [[nodiscard]] vec fma(const vec& as, const vec& bs, const vec& cs) { return zip([](T a, T b, T c) { return fma(a, b, c); }, as, bs, cs); } @@ -548,7 +548,7 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - vec ldexp(const vec& xs, const vec& exps) { + [[nodiscard]] vec ldexp(const vec& xs, const vec& exps) { return zip([](T x, int exp) { return ldexp(x, exp); }, xs, exps); } } @@ -560,39 +560,39 @@ namespace vmath_hpp namespace vmath_hpp { template < typename T, std::size_t Size > - constexpr T dot(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr T dot(const vec& xs, const vec& ys) { return fold([](T acc, T x, T y){ return acc + (x * y); }, T(0), xs, ys); } template < typename T, std::size_t Size > - T length(const vec& xs) { + [[nodiscard]] T length(const vec& xs) { return sqrt(dot(xs, xs)); } template < typename T, std::size_t Size > - constexpr T length2(const vec& xs) { + [[nodiscard]] constexpr T length2(const vec& xs) { return dot(xs, xs); } template < typename T, std::size_t Size > - T distance(const vec& xs, const vec& ys) { + [[nodiscard]] T distance(const vec& xs, const vec& ys) { return length(ys - xs); } template < typename T, std::size_t Size > - constexpr T distance2(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr T distance2(const vec& xs, const vec& ys) { return length2(ys - xs); } template < typename T > - constexpr T cross(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr T cross(const vec& xs, const vec& ys) { return xs.x * ys.y - xs.y * ys.x; } template < typename T > - constexpr vec cross(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec cross(const vec& xs, const vec& ys) { return { xs.y * ys.z - xs.z * ys.y, xs.z * ys.x - xs.x * ys.z, @@ -600,22 +600,22 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - vec normalize(const vec& xs) { + [[nodiscard]] vec normalize(const vec& xs) { return xs * rsqrt(dot(xs, xs)); } template < typename T, std::size_t Size > - constexpr vec faceforward(const vec& n, const vec& i, const vec& nref) { + [[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 > - constexpr vec reflect(const vec& i, const vec& n) { + [[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 > - vec refract(const vec& i, const vec& n, T eta) { + [[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); @@ -629,52 +629,52 @@ namespace vmath_hpp namespace vmath_hpp { template < typename T, std::size_t Size > - constexpr vec less(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec less(const vec& xs, const vec& ys) { return zip([](T x, T y){ return less(x, y); }, xs, ys); } template < typename T, std::size_t Size > - constexpr vec less_equal(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec less_equal(const vec& xs, const vec& ys) { return zip([](T x, T y){ return less_equal(x, y); }, xs, ys); } template < typename T, std::size_t Size > - constexpr vec greater(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec greater(const vec& xs, const vec& ys) { return zip([](T x, T y){ return greater(x, y); }, xs, ys); } template < typename T, std::size_t Size > - constexpr vec greater_equal(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec greater_equal(const vec& xs, const vec& ys) { return zip([](T x, T y){ return greater_equal(x, y); }, xs, ys); } template < typename T, std::size_t Size > - constexpr vec equal_to(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec equal_to(const vec& xs, const vec& ys) { return zip([](T x, T y){ return equal_to(x, y); }, xs, ys); } template < typename T, std::size_t Size > - constexpr vec equal_to(const vec& xs, const vec& ys, const T& epsilon) { + [[nodiscard]] constexpr vec equal_to(const vec& xs, const vec& ys, T epsilon) { return zip([epsilon](T x, T y){ return equal_to(x, y, epsilon); }, xs, ys); } template < typename T, std::size_t Size > - constexpr vec not_equal_to(const vec& xs, const vec& ys) { + [[nodiscard]] constexpr vec not_equal_to(const vec& xs, const vec& ys) { return zip([](T x, T y){ return not_equal_to(x, y); }, xs, ys); } template < typename T, std::size_t Size > - constexpr vec not_equal_to(const vec& xs, const vec& ys, const T& epsilon) { + [[nodiscard]] constexpr vec not_equal_to(const vec& xs, const vec& ys, T epsilon) { return zip([epsilon](T x, T y){ return not_equal_to(x, y, epsilon); }, xs, ys); } - template < std::size_t Size > - constexpr bool any(const vec& xs) { - return fold([](bool x, bool y){ return x || y; }, false, xs); + template < typename T, std::size_t Size > + [[nodiscard]] constexpr bool any(const vec& xs) { + return fold([](bool acc, T x){ return acc || any(x); }, false, xs); } - template < std::size_t Size > - constexpr bool all(const vec& xs) { - return fold([](bool x, bool y){ return x && y; }, true, xs); + template < typename T, std::size_t Size > + [[nodiscard]] constexpr bool all(const vec& xs) { + return fold([](bool acc, T x){ return acc && all(x); }, true, xs); } } diff --git a/untests/vmath_mat_fun_tests.cpp b/untests/vmath_mat_fun_tests.cpp index 4edfae7..d50d414 100644 --- a/untests/vmath_mat_fun_tests.cpp +++ b/untests/vmath_mat_fun_tests.cpp @@ -35,6 +35,32 @@ namespace } TEST_CASE("vmath/mat_fun") { + SECTION("Detail") { + STATIC_REQUIRE(map([](const int2& x){ + return x * 2; + }, int2x2{}) == int2x2(2,0,0,2)); + + STATIC_REQUIRE(zip([](const int2& x, const int2& y){ + return x + y; + }, int2x2{}, int2x2{}) == int2x2(2,0,0,2)); + + STATIC_REQUIRE(zip([](const int2& x, const int2& y, const int2& z){ + return x + y + z; + }, int2x2{}, int2x2{}, int2x2{}) == int2x2(3,0,0,3)); + + STATIC_REQUIRE(fold([](int acc, const int2& x){ + return acc + x.x; + }, 0, int2x2{}) == 1); + + STATIC_REQUIRE(fold([](int acc, const int2& x, const int2& y){ + return acc + x.x + y.x; + }, 0, int2x2{}, int2x2{}) == 2); + + STATIC_REQUIRE(fold1([](const int2& acc, const int2& x){ + return acc + x; + }, int2x2{}) == int2(1,1)); + } + SECTION("Operators") { STATIC_REQUIRE(-int2x2(1,2,3,4) == int2x2(-1,-2,-3,-4)); @@ -157,9 +183,9 @@ TEST_CASE("vmath/mat_fun") { STATIC_REQUIRE(determinant(transpose(generate_frank_matrix())) == 1); } { - STATIC_REQUIRE(inverse(int2x2()) == int2x2()); - STATIC_REQUIRE(inverse(int3x3()) == int3x3()); - STATIC_REQUIRE(inverse(int4x4()) == int4x4()); + STATIC_REQUIRE(inverse(float2x2()) == float2x2()); + STATIC_REQUIRE(inverse(float3x3()) == float3x3()); + STATIC_REQUIRE(inverse(float4x4()) == float4x4()); STATIC_REQUIRE(inverse(float2x2(0.5)) == float2x2(2.f)); STATIC_REQUIRE(inverse(float3x3(0.5)) == float3x3(2.f)); diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 1fdb10a..3dbfb53 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -18,6 +18,32 @@ namespace } TEST_CASE("vmath/vec_fun") { + SECTION("Detail") { + STATIC_REQUIRE(map([](const int& x){ + return x * 2; + }, int2{1}) == int2{2}); + + STATIC_REQUIRE(zip([](const int& x, const int& y){ + return x + y; + }, int2{1}, int2{1}) == int2{2}); + + STATIC_REQUIRE(zip([](const int& x, const int& y, const int& z){ + return x + y + z; + }, int2{1}, int2{1}, int2{1}) == int2(3)); + + STATIC_REQUIRE(fold([](int acc, const int& x){ + return acc + x; + }, 0, int2{1}) == 2); + + STATIC_REQUIRE(fold([](int acc, const int& x, const int& y){ + return acc + x + y; + }, 0, int2{1}, int2{1}) == 4); + + STATIC_REQUIRE(fold1([](const int& acc, const int& x){ + return acc + x; + }, int2{1}) == 2); + } + SECTION("Operators") { STATIC_REQUIRE(-int2(1,-2) == int2(-1,2)); @@ -99,8 +125,8 @@ TEST_CASE("vmath/vec_fun") { } SECTION("Common Functions") { - REQUIRE(abs(float2(1.f, -1.f)) == approx2(1.f,1.f)); - REQUIRE(sign(float3(1.f, -1.f, 0.f)) == approx3(1.f,-1.f,0.f)); + STATIC_REQUIRE(abs(float2(1.f, -1.f)) == approx2(1.f,1.f)); + STATIC_REQUIRE(sign(float3(1.f, -1.f, 0.f)) == approx3(1.f,-1.f,0.f)); (void)floor(float2(1.f, -1.f)); (void)trunc(float2(1.f, -1.f)); @@ -201,19 +227,19 @@ TEST_CASE("vmath/vec_fun") { STATIC_REQUIRE(any(bool2(false, true))); STATIC_REQUIRE(any(bool2(true, true))); - STATIC_REQUIRE_FALSE(any(bool2(0, 0))); - STATIC_REQUIRE(any(bool2(1, 0))); - STATIC_REQUIRE(any(bool2(0, 1))); - STATIC_REQUIRE(any(bool2(1, 1))); + STATIC_REQUIRE_FALSE(any(int2(0, 0))); + STATIC_REQUIRE(any(int2(1, 0))); + STATIC_REQUIRE(any(int2(0, 1))); + STATIC_REQUIRE(any(int2(1, 1))); STATIC_REQUIRE_FALSE(all(bool2(false, false))); STATIC_REQUIRE_FALSE(all(bool2(true, false))); STATIC_REQUIRE_FALSE(all(bool2(false, true))); STATIC_REQUIRE(all(bool2(true, true))); - STATIC_REQUIRE_FALSE(all(bool2(0, 0))); - STATIC_REQUIRE_FALSE(all(bool2(1, 0))); - STATIC_REQUIRE_FALSE(all(bool2(0, 1))); - STATIC_REQUIRE(all(bool2(1, 1))); + STATIC_REQUIRE_FALSE(all(int2(0, 0))); + STATIC_REQUIRE_FALSE(all(int2(1, 0))); + STATIC_REQUIRE_FALSE(all(int2(0, 1))); + STATIC_REQUIRE(all(int2(1, 1))); } }