diff --git a/README.md b/README.md index cbb55a8..b1c9f86 100644 --- a/README.md +++ b/README.md @@ -188,9 +188,9 @@ using size2 = vec; using size3 = vec; using size4 = vec; -using ptrdiff2 = vec; -using ptrdiff3 = vec; -using ptrdiff4 = vec; +using ptrdiff2 = vec; +using ptrdiff3 = vec; +using ptrdiff4 = vec; ``` ### Matrix Types @@ -360,9 +360,9 @@ using size2x2 = mat; using size3x3 = mat; using size4x4 = mat; -using ptrdiff2x2 = mat; -using ptrdiff3x3 = mat; -using ptrdiff4x4 = mat; +using ptrdiff2x2 = mat; +using ptrdiff3x3 = mat; +using ptrdiff4x4 = mat; ``` ### Vector Operators @@ -373,6 +373,16 @@ using ptrdiff4x4 = mat; template < typename T, size_t Size > constexpr vec operator-(const vec& xs); +// ~operator + +template < typename T, size_t Size > +constexpr vec operator~(const vec& xs); + +// !operator + +template < typename T, size_t Size > +constexpr vec operator!(const vec& xs); + // operator+ template < typename T, size_t Size > @@ -449,11 +459,92 @@ constexpr vec& operator/=(vec& xs, T y); template < typename T, size_t Size > constexpr vec& operator/=(vec& xs, const vec& ys); +// operator& + +template < typename T, size_t Size > +constexpr vec operator&(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec operator&(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec operator&(const vec& xs, const vec& ys); + +// operator&= + +template < typename T, size_t Size > +constexpr vec& operator&=(vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec& operator&=(vec& xs, const vec& ys); + +// operator| + +template < typename T, size_t Size > +constexpr vec operator|(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec operator|(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec operator|(const vec& xs, const vec& ys); + +// operator|= + +template < typename T, size_t Size > +constexpr vec& operator|=(vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec& operator|=(vec& xs, const vec& ys); + +// operator^ + +template < typename T, size_t Size > +constexpr vec operator^(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec operator^(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec operator^(const vec& xs, const vec& ys); + +// operator^= + +template < typename T, size_t Size > +constexpr vec& operator^=(vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec& operator^=(vec& xs, const vec& ys); + +// operator&& + +template < typename T, size_t Size > +constexpr vec operator&&(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec operator&&(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec operator&&(const vec& xs, const vec& ys); + +// operator|| + +template < typename T, size_t Size > +constexpr vec operator||(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec operator||(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec operator||(const vec& xs, const vec& ys); + // operator== template < typename T, size_t Size > constexpr bool operator==(const vec& xs, const vec& ys); +// operator!= + template < typename T, size_t Size > constexpr bool operator!=(const vec& xs, const vec& ys); @@ -471,6 +562,16 @@ constexpr bool operator<(const vec& xs, const vec& ys); template < typename T, size_t Size > constexpr mat operator-(const mat& xs); +// ~operator + +template < typename T, size_t Size > +constexpr mat operator~(const mat& xs); + +// !operator + +template < typename T, size_t Size > +constexpr mat operator!(const mat& xs); + // operator+ template < typename T, size_t Size > @@ -542,22 +643,97 @@ constexpr mat operator/(const mat& xs, T y); template < typename T, size_t Size > constexpr mat operator/(T x, const mat& ys); -template < typename T, size_t Size > -constexpr mat operator/(const mat& xs, const mat& ys); - // operator/= template < typename T, size_t Size > constexpr mat& operator/=(mat& xs, T y); +// operator& + template < typename T, size_t Size > -constexpr mat& operator/=(mat& xs, const mat& ys); +constexpr mat operator&(const mat& xs, T y); + +template < typename T, size_t Size > +constexpr mat operator&(T x, const mat& ys); + +template < typename T, size_t Size > +constexpr mat operator&(const mat& xs, const mat& ys); + +// operator&= + +template < typename T, size_t Size > +constexpr mat& operator&=(mat& xs, T y); + +template < typename T, size_t Size > +constexpr mat& operator&=(mat& xs, const mat& ys); + +// operator| + +template < typename T, size_t Size > +constexpr mat operator|(const mat& xs, T y); + +template < typename T, size_t Size > +constexpr mat operator|(T x, const mat& ys); + +template < typename T, size_t Size > +constexpr mat operator|(const mat& xs, const mat& ys); + +// operator|= + +template < typename T, size_t Size > +constexpr mat& operator|=(mat& xs, T y); + +template < typename T, size_t Size > +constexpr mat& operator|=(mat& xs, const mat& ys); + +// operator^ + +template < typename T, size_t Size > +constexpr mat operator^(const mat& xs, T y); + +template < typename T, size_t Size > +constexpr mat operator^(T x, const mat& ys); + +template < typename T, size_t Size > +constexpr mat operator^(const mat& xs, const mat& ys); + +// operator^= + +template < typename T, size_t Size > +constexpr mat& operator^=(mat& xs, T y); + +template < typename T, size_t Size > +constexpr mat& operator^=(mat& xs, const mat& ys); + +// operator&& + +template < typename T, size_t Size > +constexpr mat operator&&(const mat& xs, T y); + +template < typename T, size_t Size > +constexpr mat operator&&(T x, const mat& ys); + +template < typename T, size_t Size > +constexpr mat operator&&(const mat& xs, const mat& ys); + +// operator|| + +template < typename T, size_t Size > +constexpr mat operator||(const mat& xs, T y); + +template < typename T, size_t Size > +constexpr mat operator||(T x, const mat& ys); + +template < typename T, size_t Size > +constexpr mat operator||(const mat& xs, const mat& ys); // operator== template < typename T, size_t Size > constexpr bool operator==(const mat& xs, const mat& ys); +// operator!= + template < typename T, size_t Size > constexpr bool operator!=(const mat& xs, const mat& ys); @@ -569,9 +745,9 @@ constexpr bool operator<(const mat& xs, const mat& ys); ### Angle and Trigonometry Functions -```cpp -// Scalar +#### Scalar +```cpp template < floating_point T > constexpr T radians(T degrees) noexcept; @@ -618,13 +794,15 @@ template < floating_point T > T atanh(T x) noexcept; template < floating_point T > -std::pair sincos(T x) noexcept; +pair sincos(T x) noexcept; template < floating_point T > void sincos(T x, T* s, T* c) noexcept; +``` -// Vector +#### Vector +```cpp template < typename T, size_t Size > constexpr vec radians(const vec& degrees); @@ -676,9 +854,9 @@ void sincos(const vec& xs, vec* ss, vec* cs); ### Exponential Functions -```cpp -// Scalar +#### Scalar +```cpp template < floating_point T > T pow(T x, T y) noexcept; @@ -699,9 +877,11 @@ T sqrt(T x) noexcept; template < floating_point T > T rsqrt(T x) noexcept; +``` -// Vector +#### Vector +```cpp template < typename T, size_t Size > vec pow(const vec& xs, const vec& ys); @@ -726,9 +906,9 @@ vec rsqrt(const vec& xs); ### Common Functions -```cpp -// Scalar +#### Scalar +```cpp template < arithmetic T > constexpr T abs(T x) noexcept; @@ -736,7 +916,7 @@ template < arithmetic T > constexpr T sign(T x) noexcept; template < floating_point T > -constexpr T reciprocal(T x) noexcept; +constexpr T rcp(T x) noexcept; template < floating_point T > T floor(T x) noexcept; @@ -763,13 +943,13 @@ template < arithmetic T > constexpr T min(T x, T y) noexcept; template < arithmetic T, arithmetic... Ts > -constexpr std::common_type_t min(T x, T y, Ts... ts) noexcept; +constexpr common_type_t min(T x, T y, Ts... ts) noexcept; template < arithmetic T > constexpr T max(T x, T y) noexcept; template < arithmetic T, arithmetic... Ts > -constexpr std::common_type_t max(T x, T y, Ts... ts) noexcept; +constexpr common_type_t max(T x, T y, Ts... ts) noexcept; template < arithmetic T > constexpr T clamp(T x, T min_x, T max_x) noexcept; @@ -803,9 +983,11 @@ T frexp(T x, int* exp) noexcept; template < floating_point T > T ldexp(T x, int exp) noexcept; +``` -// Vector +#### Vector +```cpp template < typename T, size_t Size > constexpr vec abs(const vec& xs); @@ -813,7 +995,7 @@ template < typename T, size_t Size > constexpr vec sign(const vec& xs); template < typename T, size_t Size > -constexpr vec reciprocal(const vec& xs); +constexpr vec rcp(const vec& xs); template < typename T, size_t Size > vec floor(const vec& xs); @@ -905,9 +1087,9 @@ vec ldexp(const vec& xs, const vec& exps); ### Geometric Functions -```cpp -// Scalar +#### Scalar +```cpp template < arithmetic T > constexpr T dot(T x, T y) noexcept; @@ -934,9 +1116,11 @@ constexpr T reflect(T i, T n) noexcept; template < floating_point T > T refract(T i, T n, T eta) noexcept; +``` -// Vector +#### Vector +```cpp template < typename T, size_t Size > constexpr T dot(const vec& xs, const vec& ys); @@ -973,8 +1157,20 @@ vec refract(const vec& i, const vec& n, T eta); ### Relational Functions +#### Scalar + ```cpp -// Scalar +template < arithmetic T > +constexpr bool any(T x) noexcept; + +template < arithmetic T > +constexpr bool all(T x) noexcept; + +template < arithmetic T > +constexpr bool approx(T x, T y) noexcept; + +template < arithmetic T > +constexpr bool approx(T x, T y, T epsilon) noexcept; template < arithmetic T > constexpr bool less(T x, T y) noexcept; @@ -991,52 +1187,208 @@ constexpr bool greater_equal(T x, T y) noexcept; template < arithmetic T > constexpr bool equal_to(T x, T y) noexcept; -template < arithmetic T > -constexpr bool equal_to(T x, T y, T epsilon) noexcept; - template < arithmetic T > constexpr bool not_equal_to(T x, T y) noexcept; +``` -template < arithmetic T > -constexpr bool not_equal_to(T x, T y, T epsilon) noexcept; +#### Vector -template < arithmetic T > -constexpr bool any(T x) noexcept; - -template < arithmetic T > -constexpr bool all(T x) noexcept; - -// Vector - -template < typename T, size_t Size > -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, size_t Size > -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, size_t Size > -constexpr vec equal_to(const vec& xs, const vec& ys); - -template < typename T, size_t Size > -constexpr vec equal_to(const vec& xs, const vec& ys, T epsilon); - -template < typename T, size_t Size > -constexpr vec not_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, T epsilon); +```cpp +// any template < typename T, size_t Size > constexpr bool any(const vec& xs); +// all + template < typename T, size_t Size > constexpr bool all(const vec& xs); + +// approx + +template < typename T, size_t Size > +constexpr vec approx(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec approx(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec approx(const vec& xs, const vec& ys); + +template < typename T, size_t Size > +constexpr vec approx(const vec& xs, T y, T epsilon); + +template < typename T, size_t Size > +constexpr vec approx(T x, const vec& ys, T epsilon); + +template < typename T, size_t Size > +constexpr vec approx(const vec& xs, const vec& ys, T epsilon); + +// less + +template < typename T, size_t Size > +constexpr vec less(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec less(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec less(const vec& xs, const vec& ys); + +// less_equal + +template < typename T, size_t Size > +constexpr vec less_equal(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec less_equal(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec less_equal(const vec& xs, const vec& ys); + +// greater + +template < typename T, size_t Size > +constexpr vec greater(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec greater(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec greater(const vec& xs, const vec& ys); + +// greater_equal + +template < typename T, size_t Size > +constexpr vec greater_equal(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec greater_equal(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec greater_equal(const vec& xs, const vec& ys); + +// equal_to + +template < typename T, size_t Size > +constexpr vec equal_to(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec equal_to(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec equal_to(const vec& xs, const vec& ys); + +// not_equal_to + +template < typename T, size_t Size > +constexpr vec not_equal_to(const vec& xs, T y); + +template < typename T, size_t Size > +constexpr vec not_equal_to(T x, const vec& ys); + +template < typename T, size_t Size > +constexpr vec not_equal_to(const vec& xs, const vec& ys); +``` + +#### Matrix + +```cpp +// any + +template < typename T, size_t Size > +constexpr bool any(const mat& xs); + +// all + +template < typename T, size_t Size > +constexpr bool all(const mat& xs); + +// approx + +template < typename T, size_t Size > +constexpr mat approx(const mat& xs, T y); + +template < typename T, size_t Size > +constexpr mat approx(T x, const mat& ys); + +template < typename T, size_t Size > +constexpr mat approx(const mat& xs, const mat& ys); + +template < typename T, size_t Size > +constexpr mat approx(const mat& xs, T y, T epsilon); + +template < typename T, size_t Size > +constexpr mat approx(T x, const mat& ys, T epsilon); + +template < typename T, size_t Size > +constexpr mat approx(const mat& xs, const mat& ys, T epsilon); + +// less + +template < typename T, std::size_t Size > +constexpr mat less(const mat& xs, T y); + +template < typename T, std::size_t Size > +constexpr mat less(T x, const mat& ys); + +template < typename T, std::size_t Size > +constexpr mat less(const mat& xs, const mat& ys); + +// less_equal + +template < typename T, std::size_t Size > +constexpr mat less_equal(const mat& xs, T y); + +template < typename T, std::size_t Size > +constexpr mat less_equal(T x, const mat& ys); + +template < typename T, std::size_t Size > +constexpr mat less_equal(const mat& xs, const mat& ys); + +// greater + +template < typename T, std::size_t Size > +constexpr mat greater(const mat& xs, T y); + +template < typename T, std::size_t Size > +constexpr mat greater(T x, const mat& ys); + +template < typename T, std::size_t Size > +constexpr mat greater(const mat& xs, const mat& ys); + +// greater_equal + +template < typename T, std::size_t Size > +constexpr mat greater_equal(const mat& xs, T y); + +template < typename T, std::size_t Size > +constexpr mat greater_equal(T x, const mat& ys); + +template < typename T, std::size_t Size > +constexpr mat greater_equal(const mat& xs, const mat& ys); + +// equal_to + +template < typename T, std::size_t Size > +constexpr mat equal_to(const mat& xs, T y); + +template < typename T, std::size_t Size > +constexpr mat equal_to(T x, const mat& ys); + +template < typename T, std::size_t Size > +constexpr mat equal_to(const mat& xs, const mat& ys); + +// not_equal_to + +template < typename T, std::size_t Size > +constexpr mat not_equal_to(const mat& xs, T y); + +template < typename T, std::size_t Size > +constexpr mat not_equal_to(T x, const mat& ys); + +template < typename T, std::size_t Size > +constexpr mat not_equal_to(const mat& xs, const mat& ys); ``` ### Matrix Functions @@ -1192,8 +1544,6 @@ constexpr mat scale(const mat& m, T x, T y, T z); template < typename T > constexpr mat scale(const mat& m, const vec& v); -// look_at - template < typename T > mat look_at_lh(const vec& eye, const vec& at, const vec& up); @@ -1302,7 +1652,7 @@ vec rotate(const vec& v, T angle, const vec& normal); template < typename T > vec rotate(const vec& v, T angle, const vec& normal); -template < typename T, std::size_t Size > +template < typename T, size_t Size > vec project(const vec& v, const vec& normal); ``` diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index 67c82b2..cb17fc7 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -483,9 +483,9 @@ namespace vmath_hpp template < typename T > [[nodiscard]] mat orthographic_lh_zo(T left, T right, T bottom, T top, T znear, T zfar) { - const T sx = T(2) * reciprocal(right - left); - const T sy = T(2) * reciprocal(top - bottom); - const T sz = T(1) * reciprocal(zfar - znear); + const T sx = T(2) * rcp(right - left); + const T sy = T(2) * rcp(top - bottom); + const T sz = T(1) * rcp(zfar - znear); const T tx = - (right + left) / (right - left); const T ty = - (top + bottom) / (top - bottom); @@ -500,9 +500,9 @@ namespace vmath_hpp template < typename T > [[nodiscard]] mat orthographic_lh_no(T left, T right, T bottom, T top, T znear, T zfar) { - const T sx = T(2) * reciprocal(right - left); - const T sy = T(2) * reciprocal(top - bottom); - const T sz = T(2) * reciprocal(zfar - znear); + const T sx = T(2) * rcp(right - left); + const T sy = T(2) * rcp(top - bottom); + const T sz = T(2) * rcp(zfar - znear); const T tx = - (right + left) / (right - left); const T ty = - (top + bottom) / (top - bottom); @@ -517,9 +517,9 @@ namespace vmath_hpp template < typename T > [[nodiscard]] mat orthographic_rh_zo(T left, T right, T bottom, T top, T znear, T zfar) { - const T sx = T(2) * reciprocal(right - left); - const T sy = T(2) * reciprocal(top - bottom); - const T sz = -T(1) * reciprocal(zfar - znear); + const T sx = T(2) * rcp(right - left); + const T sy = T(2) * rcp(top - bottom); + const T sz = -T(1) * rcp(zfar - znear); const T tx = - (right + left) / (right - left); const T ty = - (top + bottom) / (top - bottom); @@ -534,9 +534,9 @@ namespace vmath_hpp template < typename T > [[nodiscard]] mat orthographic_rh_no(T left, T right, T bottom, T top, T znear, T zfar) { - const T sx = T(2) * reciprocal(right - left); - const T sy = T(2) * reciprocal(top - bottom); - const T sz = -T(2) * reciprocal(zfar - znear); + const T sx = T(2) * rcp(right - left); + const T sy = T(2) * rcp(top - bottom); + const T sz = -T(2) * rcp(zfar - znear); const T tx = - (right + left) / (right - left); const T ty = - (top + bottom) / (top - bottom); @@ -553,7 +553,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] mat perspective_lh_zo(T fov, T aspect, T znear, T zfar) { - const T sy = reciprocal(tan(fov * T(0.5))); + const T sy = rcp(tan(fov * T(0.5))); const T sx = sy / aspect; const T sz = zfar / (zfar - znear); const T tz = (znear * zfar) / (znear - zfar); @@ -566,7 +566,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] mat perspective_lh_no(T fov, T aspect, T znear, T zfar) { - const T sy = reciprocal(tan(fov * T(0.5))); + const T sy = rcp(tan(fov * T(0.5))); const T sx = sy / aspect; const T sz = (zfar + znear) / (zfar - znear); const T tz = (T(2) * znear * zfar) / (znear - zfar); @@ -579,7 +579,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] mat perspective_rh_zo(T fov, T aspect, T znear, T zfar) { - const T sy = reciprocal(tan(fov * T(0.5))); + const T sy = rcp(tan(fov * T(0.5))); const T sx = sy / aspect; const T sz = zfar / (znear - zfar); const T tz = (znear * zfar) / (znear - zfar); @@ -592,7 +592,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] mat perspective_rh_no(T fov, T aspect, T znear, T zfar) { - const T sy = reciprocal(tan(fov * T(0.5))); + const T sy = rcp(tan(fov * T(0.5))); const T sx = sy / aspect; const T sz = (zfar + znear) / (znear - zfar); const T tz = (T(2) * znear * zfar) / (znear - zfar); diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index a876bd8..997e657 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -34,7 +34,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> - constexpr reciprocal(T x) noexcept { + constexpr rcp(T x) noexcept { return T(1) / x; } @@ -331,7 +331,7 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, T> rsqrt(T x) noexcept { - return reciprocal(sqrt(x)); + return rcp(sqrt(x)); } } @@ -399,11 +399,46 @@ namespace vmath_hpp } // -// Scalar Relational Functions +// Relational Functions // namespace vmath_hpp { + template < typename T > + [[nodiscard]] std::enable_if_t, bool> + constexpr any(T x) noexcept { + return !!x; + } + + template < typename T > + [[nodiscard]] std::enable_if_t, bool> + constexpr all(T x) noexcept { + return !!x; + } + + template < typename T > + [[nodiscard]] std::enable_if_t, bool> + constexpr approx(T x, T y) noexcept { + if constexpr ( std::is_floating_point_v ) { + // http://www.realtimecollisiondetection.net/pubs/Tolerances + const T epsilon = std::numeric_limits::epsilon(); + return abs(x - y) <= epsilon * max(T(1), abs(x), abs(y)); + } else { + return x == y; + } + } + + template < typename T > + [[nodiscard]] std::enable_if_t, bool> + constexpr approx(T x, T y, T epsilon) noexcept { + if constexpr ( std::is_floating_point_v ) { + // http://www.realtimecollisiondetection.net/pubs/Tolerances + return abs(x - y) <= epsilon * max(T(1), abs(x), abs(y)); + } else { + return abs(x - y) <= epsilon; + } + } + template < typename T > [[nodiscard]] std::enable_if_t, bool> constexpr less(T x, T y) noexcept { @@ -431,47 +466,12 @@ namespace vmath_hpp template < typename T > [[nodiscard]] std::enable_if_t, bool> constexpr equal_to(T x, T y) noexcept { - if constexpr ( std::is_floating_point_v ) { - // http://www.realtimecollisiondetection.net/pubs/Tolerances - const T epsilon = std::numeric_limits::epsilon(); - return abs(x - y) <= epsilon * max(T(1), abs(x), abs(y)); - } else { - return x == y; - } - } - - template < typename T > - [[nodiscard]] std::enable_if_t, bool> - constexpr equal_to(T x, T y, T epsilon) noexcept { - if constexpr ( std::is_floating_point_v ) { - // http://www.realtimecollisiondetection.net/pubs/Tolerances - return abs(x - y) <= epsilon * max(T(1), abs(x), abs(y)); - } else { - return abs(x - y) <= epsilon; - } + return x == y; } template < typename T > [[nodiscard]] std::enable_if_t, bool> constexpr not_equal_to(T x, T y) noexcept { - return !equal_to(x, y); - } - - template < typename T > - [[nodiscard]] std::enable_if_t, bool> - constexpr not_equal_to(T x, T y, T epsilon) noexcept { - return !equal_to(x, y, epsilon); - } - - template < typename T > - [[nodiscard]] std::enable_if_t, bool> - constexpr any(T x) noexcept { - return !!x; - } - - template < typename T > - [[nodiscard]] std::enable_if_t, bool> - constexpr all(T x) noexcept { - return !!x; + return x != y; } } diff --git a/headers/vmath.hpp/vmath_mat_fun.hpp b/headers/vmath.hpp/vmath_mat_fun.hpp index 8ffc74e..572f7f1 100644 --- a/headers/vmath.hpp/vmath_mat_fun.hpp +++ b/headers/vmath.hpp/vmath_mat_fun.hpp @@ -199,6 +199,20 @@ namespace vmath_hpp return map_join([](const vec& x){ return -x; }, xs); } + // ~operator + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat 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) { + return map_join([](const vec& x){ return !x; }, xs); + } + // operator+ template < typename T, std::size_t Size > @@ -220,12 +234,12 @@ namespace vmath_hpp template < typename T, std::size_t Size > constexpr mat& operator+=(mat& xs, T y) { - return (xs = xs + y); + return (xs = (xs + y)); } template < typename T, std::size_t Size > constexpr mat& operator+=(mat& xs, const mat& ys) { - return (xs = xs + ys); + return (xs = (xs + ys)); } // operator- @@ -249,12 +263,12 @@ namespace vmath_hpp template < typename T, std::size_t Size > constexpr mat& operator-=(mat& xs, T y) { - return (xs = xs - y); + return (xs = (xs - y)); } template < typename T, std::size_t Size > constexpr mat& operator-=(mat& xs, const mat& ys) { - return (xs = xs - ys); + return (xs = (xs - ys)); } // operator* @@ -287,17 +301,17 @@ namespace vmath_hpp template < typename T, std::size_t Size > constexpr mat& operator*=(mat& xs, T y) { - return (xs = xs * y); + return (xs = (xs * y)); } template < typename T, std::size_t Size > constexpr vec& operator*=(vec& xs, const mat& ys) { - return (xs = xs * ys); + return (xs = (xs * ys)); } template < typename T, std::size_t Size > constexpr mat& operator*=(mat& xs, const mat& ys) { - return (xs = xs * ys); + return (xs = (xs * ys)); } // operator/ @@ -312,21 +326,132 @@ namespace vmath_hpp 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) { - return map_join([](const vec& x, const vec& y){ return x / y; }, xs, ys); - } - // operator/= template < typename T, std::size_t Size > constexpr mat& operator/=(mat& xs, T y) { - return (xs = xs / y); + return (xs = (xs / y)); + } + + // operator& + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat operator&(const mat& xs, T y) { + return map_join([y](const vec& x){ return x & y; }, xs); } template < typename T, std::size_t Size > - constexpr mat& operator/=(mat& xs, const mat& ys) { - return (xs = xs / ys); + [[nodiscard]] constexpr mat 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) { + return map_join([](const vec& x, const vec& y){ return x & y; }, xs, ys); + } + + // operator&= + + template < typename T, std::size_t Size > + constexpr mat& operator&=(mat& xs, T y) { + return (xs = (xs & y)); + } + + template < typename T, std::size_t Size > + constexpr mat& operator&=(mat& xs, const mat& ys) { + return (xs = (xs & ys)); + } + + // operator| + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat 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) { + 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) { + return map_join([](const vec& x, const vec& y){ return x | y; }, xs, ys); + } + + // operator|= + + template < typename T, std::size_t Size > + constexpr mat& operator|=(mat& xs, T y) { + return (xs = (xs | y)); + } + + template < typename T, std::size_t Size > + constexpr mat& operator|=(mat& xs, const mat& ys) { + return (xs = (xs | ys)); + } + + // operator^ + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat 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) { + 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) { + return map_join([](const vec& x, const vec& y){ return x ^ y; }, xs, ys); + } + + // operator^= + + template < typename T, std::size_t Size > + constexpr mat& operator^=(mat& xs, T y) { + return (xs = (xs ^ y)); + } + + template < typename T, std::size_t Size > + constexpr mat& operator^=(mat& xs, const mat& ys) { + return (xs = (xs ^ ys)); + } + + // operator&& + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat 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) { + 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) { + 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) { + 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) { + 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) { + return map_join([](const vec& x, const vec& y){ return x || y; }, xs, ys); } // operator== @@ -338,9 +463,13 @@ namespace vmath_hpp }, true, xs, ys); } + // operator!= + template < typename T, std::size_t Size > [[nodiscard]] constexpr bool operator!=(const mat& xs, const mat& ys) { - return !(xs == ys); + return fold_join([](bool acc, const vec& x, const vec& y){ + return acc || (x != y); + }, false, xs, ys); } // operator< @@ -359,6 +488,161 @@ namespace vmath_hpp } } +// +// Relational Functions +// + +namespace vmath_hpp +{ + // any + + 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); + } + + // all + + 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); + } + + // approx + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat approx(const mat& xs, T y) { + return map_join([y](const vec& x){ return approx(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat approx(T x, const mat& ys) { + return map_join([x](const vec& y){ return approx(x, y); }, ys); + } + + template < typename T, std::size_t Size > + [[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, T y, T epsilon) { + return map_join([y, epsilon](const vec& x){ return approx(x, y, epsilon); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat approx(T x, const mat& ys, T epsilon) { + return map_join([x, epsilon](const vec& y){ return approx(x, y, epsilon); }, ys); + } + + template < typename T, std::size_t Size > + [[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); + } + + // less + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat less(const mat& xs, T y) { + return map_join([y](const vec& x){ return less(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat less(T x, const mat& ys) { + return map_join([x](const vec& y){ return less(x, y); }, ys); + } + + template < typename T, std::size_t Size > + [[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); + } + + // less_equal + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat less_equal(const mat& xs, T y) { + return map_join([y](const vec& x){ return less_equal(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat less_equal(T x, const mat& ys) { + return map_join([x](const vec& y){ return less_equal(x, y); }, ys); + } + + template < typename T, std::size_t Size > + [[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); + } + + // greater + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat greater(const mat& xs, T y) { + return map_join([y](const vec& x){ return greater(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat greater(T x, const mat& ys) { + return map_join([x](const vec& y){ return greater(x, y); }, ys); + } + + template < typename T, std::size_t Size > + [[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); + } + + // greater_equal + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat greater_equal(const mat& xs, T y) { + return map_join([y](const vec& x){ return greater_equal(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat greater_equal(T x, const mat& ys) { + return map_join([x](const vec& y){ return greater_equal(x, y); }, ys); + } + + template < typename T, std::size_t Size > + [[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); + } + + // equal_to + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat equal_to(const mat& xs, T y) { + return map_join([y](const vec& x){ return equal_to(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat equal_to(T x, const mat& ys) { + return map_join([x](const vec& y){ return equal_to(x, y); }, ys); + } + + template < typename T, std::size_t Size > + [[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); + } + + // not_equal_to + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat not_equal_to(const mat& xs, T y) { + return map_join([y](const vec& x){ return not_equal_to(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr mat not_equal_to(T x, const mat& ys) { + return map_join([x](const vec& y){ return not_equal_to(x, y); }, ys); + } + + template < typename T, std::size_t Size > + [[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); + } +} + // // Matrix Functions // @@ -506,7 +790,7 @@ namespace vmath_hpp T a, T b, T c, T d) { - const T inv_det = reciprocal(determinant_2x2_impl( + const T inv_det = rcp(determinant_2x2_impl( a, b, c, d)); @@ -524,7 +808,7 @@ namespace vmath_hpp T d, T e, T f, T g, T h, T i) { - const T inv_det = reciprocal(determinant_3x3_impl( + const T inv_det = rcp(determinant_3x3_impl( a, b, c, d, e, f, g, h, i)); @@ -551,7 +835,7 @@ namespace vmath_hpp T i, T j, T k, T l, T m, T n, T o, T p) { - const T inv_det = reciprocal(determinant_4x4_impl( + const T inv_det = rcp(determinant_4x4_impl( a, b, c, d, e, f, g, h, i, j, k, l, diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index d9a0cf0..82396de 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -172,6 +172,20 @@ namespace vmath_hpp return map_join([](T x){ return -x; }, xs); } + // ~operator + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec 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) { + return map_join([](T x){ return !x; }, xs); + } + // operator+ template < typename T, std::size_t Size > @@ -193,12 +207,12 @@ namespace vmath_hpp template < typename T, std::size_t Size > constexpr vec& operator+=(vec& xs, T y) { - return (xs = xs + y); + return (xs = (xs + y)); } template < typename T, std::size_t Size > constexpr vec& operator+=(vec& xs, const vec& ys) { - return (xs = xs + ys); + return (xs = (xs + ys)); } // operator- @@ -222,12 +236,12 @@ namespace vmath_hpp template < typename T, std::size_t Size > constexpr vec& operator-=(vec& xs, T y) { - return (xs = xs - y); + return (xs = (xs - y)); } template < typename T, std::size_t Size > constexpr vec& operator-=(vec& xs, const vec& ys) { - return (xs = xs - ys); + return (xs = (xs - ys)); } // operator* @@ -251,12 +265,12 @@ namespace vmath_hpp template < typename T, std::size_t Size > constexpr vec& operator*=(vec& xs, T y) { - return (xs = xs * y); + return (xs = (xs * y)); } template < typename T, std::size_t Size > constexpr vec& operator*=(vec& xs, const vec& ys) { - return (xs = xs * ys); + return (xs = (xs * ys)); } // operator/ @@ -280,12 +294,133 @@ namespace vmath_hpp template < typename T, std::size_t Size > constexpr vec& operator/=(vec& xs, T y) { - return (xs = xs / y); + return (xs = (xs / y)); } template < typename T, std::size_t Size > constexpr vec& operator/=(vec& xs, const vec& ys) { - return (xs = xs / ys); + return (xs = (xs / ys)); + } + + // operator& + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec 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) { + 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) { + return map_join([](T x, T y){ return x & y; }, xs, ys); + } + + // operator&= + + template < typename T, std::size_t Size > + constexpr vec& operator&=(vec& xs, T y) { + return (xs = (xs & y)); + } + + template < typename T, std::size_t Size > + constexpr vec& operator&=(vec& xs, const vec& ys) { + return (xs = (xs & ys)); + } + + // operator| + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec 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) { + 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) { + return map_join([](T x, T y){ return x | y; }, xs, ys); + } + + // operator|= + + template < typename T, std::size_t Size > + constexpr vec& operator|=(vec& xs, T y) { + return (xs = (xs | y)); + } + + template < typename T, std::size_t Size > + constexpr vec& operator|=(vec& xs, const vec& ys) { + return (xs = (xs | ys)); + } + + // operator^ + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec 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) { + 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) { + return map_join([](T x, T y){ return x ^ y; }, xs, ys); + } + + // operator^= + + template < typename T, std::size_t Size > + constexpr vec& operator^=(vec& xs, T y) { + return (xs = (xs ^ y)); + } + + template < typename T, std::size_t Size > + constexpr vec& operator^=(vec& xs, const vec& ys) { + return (xs = (xs ^ ys)); + } + + // operator&& + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec 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) { + 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) { + 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) { + 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) { + 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) { + return map_join([](T x, T y){ return x || y; }, xs, ys); } // operator== @@ -293,13 +428,17 @@ namespace vmath_hpp template < typename T, std::size_t Size > [[nodiscard]] constexpr bool operator==(const vec& xs, const vec& ys) { return fold_join([](bool acc, T x, T y){ - return acc && equal_to(x, y); + return acc && x == y; }, true, xs, ys); } + // operator!= + template < typename T, std::size_t Size > [[nodiscard]] constexpr bool operator!=(const vec& xs, const vec& ys) { - return !(xs == ys); + return fold_join([](bool acc, T x, T y){ + return acc || x != y; + }, false, xs, ys); } // operator< @@ -465,8 +604,8 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec reciprocal(const vec& xs) { - return map_join([](T x) { return reciprocal(x); }, xs); + [[nodiscard]] constexpr vec rcp(const vec& xs) { + return map_join([](T x) { return rcp(x); }, xs); } template < typename T, std::size_t Size > @@ -703,58 +842,156 @@ namespace vmath_hpp } // -// Vector Relational Functions +// Relational Functions // namespace vmath_hpp { + // any + + 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); + } + + // all + + 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); + } + + // approx + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec approx(const vec& xs, T y) { + return map_join([y](T x){ return approx(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec approx(T x, const vec& ys) { + return map_join([x](T y){ return approx(x, y); }, ys); + } + + template < typename T, std::size_t Size > + [[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, T y, T epsilon) { + return map_join([y, epsilon](T x){ return approx(x, y, epsilon); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec approx(T x, const vec& ys, T epsilon) { + return map_join([x, epsilon](T y){ return approx(x, y, epsilon); }, ys); + } + + template < typename T, std::size_t Size > + [[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); + } + + // less + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec less(const vec& xs, T y) { + return map_join([y](T x){ return less(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec less(T x, const vec& ys) { + return map_join([x](T y){ return less(x, y); }, ys); + } + template < typename T, std::size_t Size > [[nodiscard]] constexpr vec less(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return less(x, y); }, xs, ys); } + // less_equal + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec less_equal(const vec& xs, T y) { + return map_join([y](T x){ return less_equal(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec less_equal(T x, const vec& ys) { + return map_join([x](T y){ return less_equal(x, y); }, ys); + } + template < typename T, std::size_t Size > [[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); } + // greater + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec greater(const vec& xs, T y) { + return map_join([y](T x){ return greater(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec greater(T x, const vec& ys) { + return map_join([x](T y){ return greater(x, y); }, ys); + } + template < typename T, std::size_t Size > [[nodiscard]] constexpr vec greater(const vec& xs, const vec& ys) { return map_join([](T x, T y){ return greater(x, y); }, xs, ys); } + // greater_equal + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec greater_equal(const vec& xs, T y) { + return map_join([y](T x){ return greater_equal(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec greater_equal(T x, const vec& ys) { + return map_join([x](T y){ return greater_equal(x, y); }, ys); + } + template < typename T, std::size_t Size > [[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); } + // equal_to + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec equal_to(const vec& xs, T y) { + return map_join([y](T x){ return equal_to(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec equal_to(T x, const vec& ys) { + return map_join([x](T y){ return equal_to(x, y); }, ys); + } + template < typename T, std::size_t Size > [[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); } + // not_equal_to + template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec equal_to(const vec& xs, const vec& ys, T epsilon) { - return map_join([epsilon](T x, T y){ return equal_to(x, y, epsilon); }, xs, ys); + [[nodiscard]] constexpr vec not_equal_to(const vec& xs, T y) { + return map_join([y](T x){ return not_equal_to(x, y); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec not_equal_to(T x, const vec& ys) { + return map_join([x](T y){ return not_equal_to(x, y); }, ys); } template < typename T, std::size_t Size > [[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); } - - template < typename T, std::size_t Size > - [[nodiscard]] constexpr vec not_equal_to(const vec& xs, const vec& ys, T epsilon) { - return map_join([epsilon](T x, T y){ return not_equal_to(x, y, epsilon); }, xs, ys); - } - - 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 > - [[nodiscard]] constexpr bool all(const vec& xs) { - return fold_join([](bool acc, T x){ return acc && all(x); }, true, xs); - } } diff --git a/untests/vmath_ext_tests.cpp b/untests/vmath_ext_tests.cpp index 51446e9..0c6ee8c 100644 --- a/untests/vmath_ext_tests.cpp +++ b/untests/vmath_ext_tests.cpp @@ -135,11 +135,11 @@ TEST_CASE("vmath/ext") { } SUBCASE("matrix translate") { - STATIC_REQUIRE(float3(2.f,3.f,1.f) * translate(float2{1.f,2.f}) == approx3(3.f,5.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * translate(translate(float2{1.f,2.f}), float2{1.f,2.f}) == approx3(4.f,7.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * translate(float2{1.f,2.f}) == uapprox3(3.f,5.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * translate(translate(float2{1.f,2.f}), float2{1.f,2.f}) == uapprox3(4.f,7.f,1.f)); - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(float3{1.f,2.f,3.f}) == approx4(3.f,5.f,7.f,1.f)); - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(translate(float3{1.f,2.f,3.f}), float3{1.f,2.f,3.f}) == approx4(4.f,7.f,10.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(float3{1.f,2.f,3.f}) == uapprox4(3.f,5.f,7.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * translate(translate(float3{1.f,2.f,3.f}), float3{1.f,2.f,3.f}) == uapprox4(4.f,7.f,10.f,1.f)); } SUBCASE("matrix rotate") { @@ -147,47 +147,47 @@ TEST_CASE("vmath/ext") { constexpr float pi_2 = radians(90.f); constexpr float pi_4 = radians(45.f); - REQUIRE(float4(0.f,1.f,0.f,1.f) * rotate_x(pi_2) == approx4(0.f,0.f,1.f,1.f)); - REQUIRE(float4(0.f,0.f,1.f,1.f) * rotate_y(pi_2) == approx4(1.f,0.f,0.f,1.f)); - REQUIRE(float4(1.f,0.f,0.f,1.f) * rotate_z(pi_2) == approx4(0.f,1.f,0.f,1.f)); + REQUIRE(float4(0.f,1.f,0.f,1.f) * rotate_x(pi_2) == uapprox4(0.f,0.f,1.f,1.f)); + REQUIRE(float4(0.f,0.f,1.f,1.f) * rotate_y(pi_2) == uapprox4(1.f,0.f,0.f,1.f)); + REQUIRE(float4(1.f,0.f,0.f,1.f) * rotate_z(pi_2) == uapprox4(0.f,1.f,0.f,1.f)); - REQUIRE(float4(0.f,1.f,0.f,1.f) * rotate_x(rotate_x(pi_4),pi_4) == approx4(0.f,0.f,1.f,1.f)); - REQUIRE(float4(0.f,0.f,1.f,1.f) * rotate_y(rotate_y(pi_4),pi_4) == approx4(1.f,0.f,0.f,1.f)); - REQUIRE(float4(1.f,0.f,0.f,1.f) * rotate_z(rotate_z(pi_4),pi_4) == approx4(0.f,1.f,0.f,1.f)); + REQUIRE(float4(0.f,1.f,0.f,1.f) * rotate_x(rotate_x(pi_4),pi_4) == uapprox4(0.f,0.f,1.f,1.f)); + REQUIRE(float4(0.f,0.f,1.f,1.f) * rotate_y(rotate_y(pi_4),pi_4) == uapprox4(1.f,0.f,0.f,1.f)); + REQUIRE(float4(1.f,0.f,0.f,1.f) * rotate_z(rotate_z(pi_4),pi_4) == uapprox4(0.f,1.f,0.f,1.f)); - REQUIRE(float3(2.f,3.f,1.f) * rotate(pi) == approx3(-2.f,-3.f,1.f)); - REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f)); - REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,float3{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f)); + REQUIRE(float3(2.f,3.f,1.f) * rotate(pi) == uapprox3(-2.f,-3.f,1.f)); + REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f)); + REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(pi,float3{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f)); - REQUIRE(float3(2.f,3.f,1.f) * rotate(rotate(pi_2),pi_2) == approx3(-2.f,-3.f,1.f)); - REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,{0.f,0.f,1.f}),pi_2,{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f)); - REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,float3{0.f,0.f,1.f}),pi_2,float3{0.f,0.f,1.f}) == approx4(-2.f,-3.f,4.f,1.f)); + REQUIRE(float3(2.f,3.f,1.f) * rotate(rotate(pi_2),pi_2) == uapprox3(-2.f,-3.f,1.f)); + REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,{0.f,0.f,1.f}),pi_2,{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f)); + REQUIRE(float4(2.f,3.f,4.f,1.f) * rotate(rotate(pi_2,float3{0.f,0.f,1.f}),pi_2,float3{0.f,0.f,1.f}) == uapprox4(-2.f,-3.f,4.f,1.f)); } SUBCASE("matrix scale") { - STATIC_REQUIRE(float3(2.f,3.f,1.f) * scale(float2{2.f,3.f}) == approx3(4.f,9.f,1.f)); - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == approx4(4.f,9.f,16.f,1.f)); - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == approx4(4.f,9.f,16.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * scale(float2{2.f,3.f}) == uapprox3(4.f,9.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == uapprox4(4.f,9.f,16.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(float3{2.f,3.f,4.f}) == uapprox4(4.f,9.f,16.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * scale(scale(float2{2.f,2.f}), {2.f,3.f}) == approx3(8.f,18.f,1.f)); - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(float3{2.f,2.f,2.f}), {2.f,3.f,4.f}) == approx4(8.f,18.f,32.f,1.f)); - STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(float3{2.f,2.f,2.f}), float3{2.f,3.f,4.f}) == approx4(8.f,18.f,32.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * scale(scale(float2{2.f,2.f}), {2.f,3.f}) == uapprox3(8.f,18.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(float3{2.f,2.f,2.f}), {2.f,3.f,4.f}) == uapprox4(8.f,18.f,32.f,1.f)); + STATIC_REQUIRE(float4(2.f,3.f,4.f,1.f) * scale(scale(float3{2.f,2.f,2.f}), float3{2.f,3.f,4.f}) == uapprox4(8.f,18.f,32.f,1.f)); } SUBCASE("matrix shear") { - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_x(0.f) == approx3(2.f,3.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_x(1.f) == approx3(5.f,3.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_x(shear_x(1.f),1.f) == approx3(8.f,3.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_x(0.f) == uapprox3(2.f,3.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_x(1.f) == uapprox3(5.f,3.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_x(shear_x(1.f),1.f) == uapprox3(8.f,3.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_y(0.f) == approx3(2.f,3.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_y(1.f) == approx3(2.f,5.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_y(shear_y(1.f),1.f) == approx3(2.f,7.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_y(0.f) == uapprox3(2.f,3.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_y(1.f) == uapprox3(2.f,5.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear_y(shear_y(1.f),1.f) == uapprox3(2.f,7.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(float2(0.f,0.f)) == approx3(2.f,3.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(float2(1.f,0.f)) == approx3(5.f,3.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(float2(0.f,1.f)) == approx3(2.f,5.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(shear(float2(1.f,0.f)),float2(1.f,0.f)) == approx3(8.f,3.f,1.f)); - STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(shear(float2(0.f,1.f)),float2(0.f,1.f)) == approx3(2.f,7.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(float2(0.f,0.f)) == uapprox3(2.f,3.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(float2(1.f,0.f)) == uapprox3(5.f,3.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(float2(0.f,1.f)) == uapprox3(2.f,5.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(shear(float2(1.f,0.f)),float2(1.f,0.f)) == uapprox3(8.f,3.f,1.f)); + STATIC_REQUIRE(float3(2.f,3.f,1.f) * shear(shear(float2(0.f,1.f)),float2(0.f,1.f)) == uapprox3(2.f,7.f,1.f)); } SUBCASE("matrix look_at") { @@ -206,24 +206,24 @@ TEST_CASE("vmath/ext") { } SUBCASE("vector angle") { - REQUIRE(angle(float2(2.f,0.f), float2(0.f,1.f)) == approx(radians(90.f))); - REQUIRE(angle(float2(0.f,3.f), float2(1.f,0.f)) == approx(radians(90.f))); - REQUIRE(angle(float2(0.5f,0.f), float2(-1.f,0.f)) == approx(radians(180.f))); - REQUIRE(angle(float2(-0.2f,0.f), float2(1.f,0.f)) == approx(radians(180.f))); - REQUIRE(angle(float3(0.f,2.f,0.f), float3(0.f,0.f,1.f)) == approx(radians(90.f))); - REQUIRE(angle(float3(0.f,0.f,3.f), float3(0.f,1.f,0.f)) == approx(radians(90.f))); + REQUIRE(angle(float2(2.f,0.f), float2(0.f,1.f)) == uapprox(radians(90.f))); + REQUIRE(angle(float2(0.f,3.f), float2(1.f,0.f)) == uapprox(radians(90.f))); + REQUIRE(angle(float2(0.5f,0.f), float2(-1.f,0.f)) == uapprox(radians(180.f))); + REQUIRE(angle(float2(-0.2f,0.f), float2(1.f,0.f)) == uapprox(radians(180.f))); + REQUIRE(angle(float3(0.f,2.f,0.f), float3(0.f,0.f,1.f)) == uapprox(radians(90.f))); + REQUIRE(angle(float3(0.f,0.f,3.f), float3(0.f,1.f,0.f)) == uapprox(radians(90.f))); } SUBCASE("vector rotate") { - REQUIRE(rotate(float2(2.f,0.f), radians(90.f)) == approx2(0.f,2.f)); - REQUIRE(rotate(float2(1.5f,0.f), radians(-90.f)) == approx2(0.f,-1.5f)); + REQUIRE(rotate(float2(2.f,0.f), radians(90.f)) == uapprox2(0.f,2.f)); + REQUIRE(rotate(float2(1.5f,0.f), radians(-90.f)) == uapprox2(0.f,-1.5f)); - REQUIRE(rotate(float3(1.5f,0.f,0.f), radians(90.f), float3(0,0,1)) == approx3(0.f,1.5f,0.f)); - REQUIRE(rotate(float4(1.5f,0.f,0.f,1.f), radians(90.f), float3(0,0,1)) == approx4(0.f,1.5f,0.f,1.f)); + REQUIRE(rotate(float3(1.5f,0.f,0.f), radians(90.f), float3(0,0,1)) == uapprox3(0.f,1.5f,0.f)); + REQUIRE(rotate(float4(1.5f,0.f,0.f,1.f), radians(90.f), float3(0,0,1)) == uapprox4(0.f,1.5f,0.f,1.f)); } SUBCASE("vector project") { - REQUIRE(project(float2(2.f, 2.f), float2(0.f, 1.f)) == approx2(0.f, 2.f)); - REQUIRE(project(float3(2.f, 2.f, 2.f), float3(0.f, 0.f, 1.f)) == approx3(0.f, 0.f, 2.f)); + REQUIRE(project(float2(2.f, 2.f), float2(0.f, 1.f)) == uapprox2(0.f, 2.f)); + REQUIRE(project(float3(2.f, 2.f, 2.f), float3(0.f, 0.f, 1.f)) == uapprox3(0.f, 0.f, 2.f)); } } diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index 33787f5..5de0161 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -15,8 +15,8 @@ namespace TEST_CASE("vmath/fun") { SUBCASE("Angle and Trigonometry Functions") { - STATIC_REQUIRE(radians(degrees(12.13f)) == approx(12.13f)); - STATIC_REQUIRE(degrees(radians(12.13f)) == approx(12.13f)); + STATIC_REQUIRE(radians(degrees(12.13f)) == uapprox(12.13f)); + STATIC_REQUIRE(degrees(radians(12.13f)) == uapprox(12.13f)); (void)sin(0.f); (void)cos(0.f); @@ -38,8 +38,8 @@ TEST_CASE("vmath/fun") { { float out_s{}, out_c{}; sincos(15.f, &out_s, &out_c); - REQUIRE(out_s == approx(sin(15.f))); - REQUIRE(out_c == approx(cos(15.f))); + REQUIRE(out_s == uapprox(sin(15.f))); + REQUIRE(out_c == uapprox(cos(15.f))); } } @@ -56,125 +56,93 @@ TEST_CASE("vmath/fun") { SUBCASE("Common Functions") { STATIC_REQUIRE(vmath_hpp::abs(1) == 1); STATIC_REQUIRE(vmath_hpp::abs(-1) == 1); - STATIC_REQUIRE(vmath_hpp::abs(1.f) == approx(1.f)); - STATIC_REQUIRE(vmath_hpp::abs(-1.f) == approx(1.f)); + STATIC_REQUIRE(vmath_hpp::abs(1.f) == uapprox(1.f)); + STATIC_REQUIRE(vmath_hpp::abs(-1.f) == uapprox(1.f)); STATIC_REQUIRE(sign(2) == 1); STATIC_REQUIRE(sign(-2) == -1); STATIC_REQUIRE(sign(0) == 0); - STATIC_REQUIRE(sign(2.f) == approx(1.f)); - STATIC_REQUIRE(sign(-2.f) == approx(-1.f)); - STATIC_REQUIRE(sign(0.f) == approx(0.f)); + STATIC_REQUIRE(sign(2.f) == uapprox(1.f)); + STATIC_REQUIRE(sign(-2.f) == uapprox(-1.f)); + STATIC_REQUIRE(sign(0.f) == uapprox(0.f)); - STATIC_REQUIRE(reciprocal(2.f) == approx(0.5f)); - STATIC_REQUIRE(reciprocal(4.f) == approx(0.25f)); + STATIC_REQUIRE(rcp(2.f) == uapprox(0.5f)); + STATIC_REQUIRE(rcp(4.f) == uapprox(0.25f)); - REQUIRE(floor(1.7f) == approx(1.f)); - REQUIRE(trunc(1.7f) == approx(1.f)); - REQUIRE(round(1.7f) == approx(2.f)); - REQUIRE(ceil(1.7f) == approx(2.f)); + REQUIRE(floor(1.7f) == uapprox(1.f)); + REQUIRE(trunc(1.7f) == uapprox(1.f)); + REQUIRE(round(1.7f) == uapprox(2.f)); + REQUIRE(ceil(1.7f) == uapprox(2.f)); - REQUIRE(fract(1.7f) == approx(0.7f)); - REQUIRE(fract(-2.3f) == approx(0.7f)); + REQUIRE(fract(1.7f) == uapprox(0.7f)); + REQUIRE(fract(-2.3f) == uapprox(0.7f)); - REQUIRE(fmod(1.7f, 1.2f) == approx(0.5f)); + REQUIRE(fmod(1.7f, 1.2f) == uapprox(0.5f)); { float out_i{}; - REQUIRE(modf(1.7f, &out_i) == approx(0.7f)); - REQUIRE(out_i == approx(1.f)); + REQUIRE(modf(1.7f, &out_i) == uapprox(0.7f)); + REQUIRE(out_i == uapprox(1.f)); } - STATIC_REQUIRE(min(0.f, 1.f) == approx(0.f)); - STATIC_REQUIRE(min(3.f, 2.f, 1.f) == approx(1.f)); - STATIC_REQUIRE(min(4.f, 3.f, 2.f, 1.f) == approx(1.f)); + STATIC_REQUIRE(min(0.f, 1.f) == uapprox(0.f)); + STATIC_REQUIRE(min(3.f, 2.f, 1.f) == uapprox(1.f)); + STATIC_REQUIRE(min(4.f, 3.f, 2.f, 1.f) == uapprox(1.f)); - STATIC_REQUIRE(max(0.f, 1.f) == approx(1.f)); - STATIC_REQUIRE(max(3.f, 2.f, 1.f) == approx(3.f)); - STATIC_REQUIRE(max(4.f, 3.f, 2.f, 1.f) == approx(4.f)); + STATIC_REQUIRE(max(0.f, 1.f) == uapprox(1.f)); + STATIC_REQUIRE(max(3.f, 2.f, 1.f) == uapprox(3.f)); + STATIC_REQUIRE(max(4.f, 3.f, 2.f, 1.f) == uapprox(4.f)); - STATIC_REQUIRE(clamp(1.0f, 2.f, 3.f) == approx(2.0f)); - STATIC_REQUIRE(clamp(2.5f, 2.f, 3.f) == approx(2.5f)); - STATIC_REQUIRE(clamp(3.5f, 2.f, 3.f) == approx(3.0f)); + STATIC_REQUIRE(clamp(1.0f, 2.f, 3.f) == uapprox(2.0f)); + STATIC_REQUIRE(clamp(2.5f, 2.f, 3.f) == uapprox(2.5f)); + STATIC_REQUIRE(clamp(3.5f, 2.f, 3.f) == uapprox(3.0f)); - STATIC_REQUIRE(saturate(-0.5f) == approx(0.f)); - STATIC_REQUIRE(saturate(0.5f) == approx(0.5f)); - STATIC_REQUIRE(saturate(1.5f) == approx(1.f)); + STATIC_REQUIRE(saturate(-0.5f) == uapprox(0.f)); + STATIC_REQUIRE(saturate(0.5f) == uapprox(0.5f)); + STATIC_REQUIRE(saturate(1.5f) == uapprox(1.f)); - STATIC_REQUIRE(lerp(0.f, 10.f, 0.5f) == approx(5.f)); - STATIC_REQUIRE(step(0.5f, 0.4f) == approx(0.f)); - STATIC_REQUIRE(step(0.5f, 0.6f) == approx(1.f)); - STATIC_REQUIRE(smoothstep(0.f, 1.f, 0.1f) == approx(0.028f)); + STATIC_REQUIRE(lerp(0.f, 10.f, 0.5f) == uapprox(5.f)); + STATIC_REQUIRE(step(0.5f, 0.4f) == uapprox(0.f)); + STATIC_REQUIRE(step(0.5f, 0.6f) == uapprox(1.f)); + STATIC_REQUIRE(smoothstep(0.f, 1.f, 0.1f) == uapprox(0.028f)); REQUIRE_FALSE(vmath_hpp::isnan(1.f)); REQUIRE_FALSE(vmath_hpp::isinf(1.f)); REQUIRE(vmath_hpp::isfinite(1.f)); - REQUIRE(fma(2.f, 3.f, 4.f) == approx(10.f)); + REQUIRE(fma(2.f, 3.f, 4.f) == uapprox(10.f)); { int out_exp{}; - REQUIRE(frexp(1.7f, &out_exp) == approx(0.85f)); + REQUIRE(frexp(1.7f, &out_exp) == uapprox(0.85f)); REQUIRE(out_exp == 1); } - REQUIRE(ldexp(0.85f, 1) == approx(1.7f)); + REQUIRE(ldexp(0.85f, 1) == uapprox(1.7f)); } SUBCASE("Geometric Functions") { - STATIC_REQUIRE(length(10.f) == approx(10.f)); - STATIC_REQUIRE(length(-10.f) == approx(10.f)); + STATIC_REQUIRE(length(10.f) == uapprox(10.f)); + STATIC_REQUIRE(length(-10.f) == uapprox(10.f)); - STATIC_REQUIRE(length2(10.f) == approx(100.f)); - STATIC_REQUIRE(length2(-10.f) == approx(100.f)); + STATIC_REQUIRE(length2(10.f) == uapprox(100.f)); + STATIC_REQUIRE(length2(-10.f) == uapprox(100.f)); - STATIC_REQUIRE(distance(5.f, 10.f) == approx(5.f)); - STATIC_REQUIRE(distance(-5.f, -10.f) == approx(5.f)); + STATIC_REQUIRE(distance(5.f, 10.f) == uapprox(5.f)); + STATIC_REQUIRE(distance(-5.f, -10.f) == uapprox(5.f)); - STATIC_REQUIRE(distance2(5.f, 10.f) == approx(25.f)); - STATIC_REQUIRE(distance2(-5.f, -10.f) == approx(25.f)); + STATIC_REQUIRE(distance2(5.f, 10.f) == uapprox(25.f)); + STATIC_REQUIRE(distance2(-5.f, -10.f) == uapprox(25.f)); - STATIC_REQUIRE(dot(2.f, 5.f) == approx(10.f)); - REQUIRE(normalize(0.5f) == approx(1.f)); + STATIC_REQUIRE(dot(2.f, 5.f) == uapprox(10.f)); + REQUIRE(normalize(0.5f) == uapprox(1.f)); - STATIC_REQUIRE(faceforward(1.f, 2.f, 3.f) == approx(-1.f)); - STATIC_REQUIRE(reflect(1.f, 2.f) == approx(-7.f)); - REQUIRE(refract(1.f, 2.f, 1.f) == approx(-7.f)); + STATIC_REQUIRE(faceforward(1.f, 2.f, 3.f) == uapprox(-1.f)); + STATIC_REQUIRE(reflect(1.f, 2.f) == uapprox(-7.f)); + REQUIRE(refract(1.f, 2.f, 1.f) == uapprox(-7.f)); } - SUBCASE("Scalar Relational Functions") { - STATIC_REQUIRE(less(0, 1)); - STATIC_REQUIRE(less_equal(0, 1)); - STATIC_REQUIRE_FALSE(less(1, 1)); - STATIC_REQUIRE(less_equal(1, 1)); - - STATIC_REQUIRE(greater(1, 0)); - STATIC_REQUIRE(greater_equal(1, 0)); - STATIC_REQUIRE_FALSE(greater(1, 1)); - STATIC_REQUIRE(greater_equal(1, 1)); - - STATIC_REQUIRE(equal_to(1, 1)); - STATIC_REQUIRE_FALSE(equal_to(0, 1)); - STATIC_REQUIRE_FALSE(equal_to(0, 1, 0)); - STATIC_REQUIRE(equal_to(0, 1, 1)); - - STATIC_REQUIRE(not_equal_to(0, 1)); - STATIC_REQUIRE(not_equal_to(0, 1, 0)); - STATIC_REQUIRE_FALSE(not_equal_to(0, 1, 1)); - STATIC_REQUIRE_FALSE(not_equal_to(1, 1)); - STATIC_REQUIRE_FALSE(not_equal_to(1, 1, 0)); - STATIC_REQUIRE_FALSE(not_equal_to(1, 1, 1)); - - STATIC_REQUIRE(equal_to(1.f, 1.f + std::numeric_limits::epsilon() * 0.5f)); - STATIC_REQUIRE_FALSE(equal_to(1.f, 1.f + std::numeric_limits::epsilon() * 1.5f)); - STATIC_REQUIRE(equal_to(100.f, 100.f + std::numeric_limits::epsilon() * 90.f)); - STATIC_REQUIRE_FALSE(equal_to(100.f, 100.f + std::numeric_limits::epsilon() * 110.f)); - - STATIC_REQUIRE_FALSE(not_equal_to(1.f, 1.f + std::numeric_limits::epsilon() * 0.5f)); - STATIC_REQUIRE(not_equal_to(1.f, 1.f + std::numeric_limits::epsilon() * 1.5f)); - STATIC_REQUIRE_FALSE(not_equal_to(100.f, 100.f + std::numeric_limits::epsilon() * 90.f)); - STATIC_REQUIRE(not_equal_to(100.f, 100.f + std::numeric_limits::epsilon() * 110.f)); - + SUBCASE("Relational Functions") { STATIC_REQUIRE_FALSE(any(false)); STATIC_REQUIRE_FALSE(any(0)); STATIC_REQUIRE(any(true)); @@ -184,5 +152,15 @@ TEST_CASE("vmath/fun") { STATIC_REQUIRE_FALSE(all(0)); STATIC_REQUIRE(all(true)); STATIC_REQUIRE(all(1)); + + STATIC_REQUIRE(approx(1, 1)); + STATIC_REQUIRE_FALSE(approx(0, 1)); + STATIC_REQUIRE_FALSE(approx(0, 1, 0)); + STATIC_REQUIRE(approx(0, 1, 1)); + + STATIC_REQUIRE(approx(1.f, 1.f + std::numeric_limits::epsilon() * 0.5f)); + STATIC_REQUIRE_FALSE(approx(1.f, 1.f + std::numeric_limits::epsilon() * 1.5f)); + STATIC_REQUIRE(approx(100.f, 100.f + std::numeric_limits::epsilon() * 90.f)); + STATIC_REQUIRE_FALSE(approx(100.f, 100.f + std::numeric_limits::epsilon() * 110.f)); } } diff --git a/untests/vmath_mat_fun_tests.cpp b/untests/vmath_mat_fun_tests.cpp index c8b7069..6c249f3 100644 --- a/untests/vmath_mat_fun_tests.cpp +++ b/untests/vmath_mat_fun_tests.cpp @@ -59,20 +59,31 @@ TEST_CASE("vmath/mat_fun") { SUBCASE("operators") { STATIC_REQUIRE(-int2x2(1,2,3,4) == int2x2(-1,-2,-3,-4)); + STATIC_REQUIRE(~uint2x2(0xF0F0F0F0,0x0F0F0F0F,0xF0F0F0F0,0x0F0F0F0F) == uint2x2(0x0F0F0F0F,0xF0F0F0F0,0x0F0F0F0F,0xF0F0F0F0)); + STATIC_REQUIRE(!int2x2(-1,0,1,2) == bool2x2(false,true,false,false)); STATIC_REQUIRE(int2x2(1,2,3,4) + 2 == int2x2(3,4,5,6)); STATIC_REQUIRE(int2x2(1,2,3,4) - 2 == int2x2(-1,0,1,2)); STATIC_REQUIRE(int2x2(1,2,3,4) * 2 == int2x2(2,4,6,8)); STATIC_REQUIRE(int2x2(1,2,3,4) / 2 == int2x2(0,1,1,2)); + STATIC_REQUIRE((int2x2(11,12,11,12) & 6) == int2x2(2,4,2,4)); + STATIC_REQUIRE((int2x2(11,12,11,12) | 6) == int2x2(15,14,15,14)); + STATIC_REQUIRE((int2x2(11,12,11,12) ^ 6) == int2x2(13,10,13,10)); + STATIC_REQUIRE((int2x2(1,0,1,0) && 1) == bool2x2(1,0,1,0)); + STATIC_REQUIRE((int2x2(1,0,1,0) || 1) == bool2x2(1,1,1,1)); STATIC_REQUIRE(4 + int2x2(1,2,3,4) == int2x2(5,6,7,8)); STATIC_REQUIRE(4 - int2x2(1,2,3,4) == int2x2(3,2,1,0)); STATIC_REQUIRE(4 * int2x2(1,2,3,4) == int2x2(4,8,12,16)); STATIC_REQUIRE(4 / int2x2(1,2,3,4) == int2x2(4,2,1,1)); + STATIC_REQUIRE((6 &int2x2(11,12,11,12)) == int2x2(2,4,2,4)); + STATIC_REQUIRE((6 |int2x2(11,12,11,12)) == int2x2(15,14,15,14)); + STATIC_REQUIRE((6 ^ int2x2(11,12,11,12)) == int2x2(13,10,13,10)); + STATIC_REQUIRE((1 && int2x2(1,0,1,0)) == bool2x2(1,0,1,0)); + STATIC_REQUIRE((1 || int2x2(1,0,1,0)) == bool2x2(1,1,1,1)); STATIC_REQUIRE(int2x2(1,2,3,4) + int2x2(5,6,7,8) == int2x2(6,8,10,12)); STATIC_REQUIRE(int2x2(1,2,3,4) - int2x2(5,6,7,8) == int2x2(-4,-4,-4,-4)); - STATIC_REQUIRE(int2x2(5,6,7,8) / int2x2(1,2,3,4) == int2x2(5,3,2,2)); STATIC_REQUIRE(int2x2() * int2x2() == int2x2()); STATIC_REQUIRE(int3x3() * int3x3() == int3x3()); @@ -81,6 +92,12 @@ TEST_CASE("vmath/mat_fun") { STATIC_REQUIRE(int3(1,2,3) * int3x3() == int3(1,2,3)); STATIC_REQUIRE(int4(1,2,3,4) * int4x4() == int4(1,2,3,4)); + STATIC_REQUIRE((int2x2(6,7,6,7) & int2x2(11,12,11,12)) == int2x2(2,4,2,4)); + STATIC_REQUIRE((int2x2(6,7,6,7) | int2x2(11,12,11,12)) == int2x2(15,15,15,15)); + STATIC_REQUIRE((int2x2(6,7,6,7) ^ int2x2(11,12,11,12)) == int2x2(13,11,13,11)); + STATIC_REQUIRE((int2x2(0,1,0,1) && int2x2(1,0,1,0)) == bool2x2(0,0,0,0)); + STATIC_REQUIRE((int2x2(0,1,0,1) || int2x2(1,0,1,0)) == bool2x2(1,1,1,1)); + { int2x2 v{1,2,3,4}; REQUIRE(&v == &(v += 3)); @@ -100,18 +117,10 @@ TEST_CASE("vmath/mat_fun") { REQUIRE(&v == &(v *= 3)); REQUIRE(v == int2x2{3,6,9,12}); } - { - int2x2 v{6,18,36,60}; - REQUIRE(&v == &(v /= 2)); - REQUIRE(v == int2x2{3,9,18,30}); - REQUIRE(&v == &(v /= int2x2{3,4,3,10})); - REQUIRE(v == int2x2{1,2,6,3}); - } - { int4 v{0, 0, 0, 1}; REQUIRE(&v == &(v *= translate(int3{1,2,3}))); - REQUIRE(v == approx4(1,2,3,1)); + REQUIRE(v == uapprox4(1,2,3,1)); } { int3 v{1, 2, 3}; @@ -128,6 +137,92 @@ TEST_CASE("vmath/mat_fun") { REQUIRE(&v == &(v *= int3x3(scale(int3{2,3,4})))); REQUIRE(v == int3x3(scale(int3{2,6,12}))); } + { + int2x2 v1{11,12,11,12}; + REQUIRE(&v1 == &(v1 &= 6)); + REQUIRE(v1 == int2x2(2,4,2,4)); + int2x2 v2{6,7,6,7}; + REQUIRE(&v2 == &(v2 &= int2x2(11,12,11,12))); + REQUIRE(v2 == int2x2(2,4,2,4)); + } + { + int2x2 v1{11,12,11,12}; + REQUIRE(&v1 == &(v1 |= 6)); + REQUIRE(v1 == int2x2(15,14,15,14)); + int2x2 v2{6,7,6,7}; + REQUIRE(&v2 == &(v2 |= int2x2(11,12,11,12))); + REQUIRE(v2 == int2x2(15,15,15,15)); + } + { + int2x2 v1{11,12,11,12}; + REQUIRE(&v1 == &(v1 ^= 6)); + REQUIRE(v1 == int2x2(13,10,13,10)); + int2x2 v2{6,7,6,7}; + REQUIRE(&v2 == &(v2 ^= int2x2(11,12,11,12))); + REQUIRE(v2 == int2x2(13,11,13,11)); + } + } + + SUBCASE("relational functions") { + STATIC_REQUIRE_FALSE(any(bool2x2(false, false, false, false))); + STATIC_REQUIRE(any(bool2x2(true, false, true, false))); + STATIC_REQUIRE(any(bool2x2(false, true, false, true))); + STATIC_REQUIRE(any(bool2x2(true, true, true, true))); + + STATIC_REQUIRE_FALSE(any(int2x2(0, 0, 0, 0))); + STATIC_REQUIRE(any(int2x2(1, 0, 1, 0))); + STATIC_REQUIRE(any(int2x2(0, 1, 0, 1))); + STATIC_REQUIRE(any(int2x2(1, 1, 1, 1))); + + STATIC_REQUIRE_FALSE(all(bool2x2(false, false, false, false))); + STATIC_REQUIRE_FALSE(all(bool2x2(true, false, true, false))); + STATIC_REQUIRE_FALSE(all(bool2x2(false, true, false, true))); + STATIC_REQUIRE(all(bool2x2(true, true, true, true))); + + STATIC_REQUIRE_FALSE(all(int2x2(0, 0, 0, 0))); + STATIC_REQUIRE_FALSE(all(int2x2(1, 0, 1, 0))); + STATIC_REQUIRE_FALSE(all(int2x2(0, 1, 0, 1))); + STATIC_REQUIRE(all(int2x2(1, 1, 1, 1))); + + STATIC_REQUIRE(approx(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(false, true, false, false)); + STATIC_REQUIRE(approx(int2x2(0,1,2,3),1) == bool2x2(false, true, false, false)); + STATIC_REQUIRE(approx(1,int2x2(0,1,2,3)) == bool2x2(false, true, false, false)); + + STATIC_REQUIRE(approx(int2x2(1,1,1,1), int2x2(0,1,2,3), 0) == bool2x2(false, true, false, false)); + STATIC_REQUIRE(approx(int2x2(0,1,2,3), 1, 0) == bool2x2(false, true, false, false)); + STATIC_REQUIRE(approx(1, int2x2(0,1,2,3), 0) == bool2x2(false, true, false, false)); + + STATIC_REQUIRE(approx(int2x2(1,1,1,1), int2x2(0,1,2,3), 1) == bool2x2(true, true, true, false)); + STATIC_REQUIRE(approx(int2x2(0,1,2,3), 1, 1) == bool2x2(true, true, true, false)); + STATIC_REQUIRE(approx(1, int2x2(0,1,2,3), 1) == bool2x2(true, true, true, false)); + + STATIC_REQUIRE(approx(int2x2(1,1,1,1), int2x2(0,1,2,3), 2) == bool2x2(true, true, true, true)); + STATIC_REQUIRE(approx(int2x2(0,1,2,3), 1, 2) == bool2x2(true, true, true, true)); + STATIC_REQUIRE(approx(1, int2x2(0,1,2,3), 2) == bool2x2(true, true, true, true)); + + STATIC_REQUIRE(less(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(false, false, true, true)); + STATIC_REQUIRE(less(int2x2(0,1,2,3), 1) == bool2x2(true, false, false, false)); + STATIC_REQUIRE(less(1, int2x2(0,1,2,3)) == bool2x2(false, false, true, true)); + + STATIC_REQUIRE(less_equal(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(false, true, true, true)); + STATIC_REQUIRE(less_equal(int2x2(0,1,2,3), 1) == bool2x2(true, true, false, false)); + STATIC_REQUIRE(less_equal(1, int2x2(0,1,2,3)) == bool2x2(false, true, true, true)); + + STATIC_REQUIRE(greater(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(true, false, false, false)); + STATIC_REQUIRE(greater(int2x2(0,1,2,3), 1) == bool2x2(false, false, true, true)); + STATIC_REQUIRE(greater(1, int2x2(0,1,2,3)) == bool2x2(true, false, false, false)); + + STATIC_REQUIRE(greater_equal(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(true, true, false, false)); + STATIC_REQUIRE(greater_equal(int2x2(0,1,2,3), 1) == bool2x2(false, true, true, true)); + STATIC_REQUIRE(greater_equal(1, int2x2(0,1,2,3)) == bool2x2(true, true, false, false)); + + STATIC_REQUIRE(equal_to(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(false, true, false, false)); + STATIC_REQUIRE(equal_to(int2x2(0,1,2,3),1) == bool2x2(false, true, false, false)); + STATIC_REQUIRE(equal_to(1,int2x2(0,1,2,3)) == bool2x2(false, true, false, false)); + + STATIC_REQUIRE(not_equal_to(int2x2(1,1,1,1), int2x2(0,1,2,3)) == bool2x2(true, false, true, true)); + STATIC_REQUIRE(not_equal_to(int2x2(0,1,2,3),1) == bool2x2(true, false, true, true)); + STATIC_REQUIRE(not_equal_to(1,int2x2(0,1,2,3)) == bool2x2(true, false, true, true)); } SUBCASE("transpose") { @@ -191,40 +286,40 @@ TEST_CASE("vmath/mat_fun") { { constexpr float4x4 m1 = translate(float3(1.f, 2.f, 3.f)); constexpr float4x4 rm1 = inverse(m1); - STATIC_REQUIRE(all(equal_to( + STATIC_REQUIRE(all(approx( unit4_z * m1 * rm1, unit4_z, - approx_epsilon_v))); + uapprox_epsilon_v))); } { const float3 axis2 = normalize(float3(1.f, 2.f, 3.f)); const float4x4 m2 = rotate(0.5f,axis2); const float4x4 rm2 = inverse(m2); - REQUIRE(all(equal_to( + REQUIRE(all(approx( unit4_z * m2 * rm2, unit4_z, - approx_epsilon_v))); + uapprox_epsilon_v))); } { const float3 axis3 = normalize(float3(1.f, 2.f, 3.f)); const float3x3 m3 = float3x3(rotate(0.5f,axis3)); const float3x3 rm3 = inverse(m3); - REQUIRE(all(equal_to( + REQUIRE(all(approx( unit3_z * m3 * rm3, unit3_z, - approx_epsilon_v))); + uapprox_epsilon_v))); } { const float3 axis4 = normalize(float3(0.f, 0.f, 3.f)); const float2x2 m4 = float2x2(rotate(0.5f,axis4)); const float2x2 rm4 = inverse(m4); - REQUIRE(all(equal_to( + REQUIRE(all(approx( unit2_y * m4 * rm4, unit2_y, - approx_epsilon_v))); + uapprox_epsilon_v))); } } } diff --git a/untests/vmath_tests.hpp b/untests/vmath_tests.hpp index f972f37..c978d46 100644 --- a/untests/vmath_tests.hpp +++ b/untests/vmath_tests.hpp @@ -13,58 +13,58 @@ namespace vmath_tests using namespace vmath_hpp; template < typename T > - struct approx_epsilon; + struct uapprox_epsilon; template <> - struct approx_epsilon { + struct uapprox_epsilon { static constexpr int value = 0; }; template <> - struct approx_epsilon { + struct uapprox_epsilon { static constexpr float value = FLT_EPSILON * 100; }; template <> - struct approx_epsilon { + struct uapprox_epsilon { static constexpr float value = DBL_EPSILON * 100; }; template < typename T > - inline constexpr T approx_epsilon_v = approx_epsilon::value; + inline constexpr T uapprox_epsilon_v = uapprox_epsilon::value; // // // template < typename T > - struct approx { + struct uapprox { T value; - explicit constexpr approx(T v) : value(v) {} + explicit constexpr uapprox(T v) : value(v) {} }; template < typename T > - struct approx2 { + struct uapprox2 { vec value; - constexpr explicit approx2(T v) : value(v) {} - constexpr explicit approx2(T x, T y) : value(x, y) {} - constexpr explicit approx2(const vec& v) : value(v) {} + constexpr explicit uapprox2(T v) : value(v) {} + constexpr explicit uapprox2(T x, T y) : value(x, y) {} + constexpr explicit uapprox2(const vec& v) : value(v) {} }; template < typename T > - struct approx3 { + struct uapprox3 { vec value; - constexpr explicit approx3(T v) : value(v) {} - constexpr explicit approx3(T x, T y, T z) : value(x, y, z) {} - constexpr explicit approx3(const vec& v) : value(v) {} + constexpr explicit uapprox3(T v) : value(v) {} + constexpr explicit uapprox3(T x, T y, T z) : value(x, y, z) {} + constexpr explicit uapprox3(const vec& v) : value(v) {} }; template < typename T > - struct approx4 { + struct uapprox4 { vec value; - constexpr explicit approx4(T v) : value(v) {} - constexpr explicit approx4(T x, T y, T z, T w) : value(x, y, z, w) {} - constexpr explicit approx4(const vec& v) : value(v) {} + constexpr explicit uapprox4(T v) : value(v) {} + constexpr explicit uapprox4(T x, T y, T z, T w) : value(x, y, z, w) {} + constexpr explicit uapprox4(const vec& v) : value(v) {} }; // @@ -72,22 +72,22 @@ namespace vmath_tests // template < typename T > - constexpr bool operator==(const T& l, const approx& r) { - return equal_to(l, r.value, approx_epsilon_v); + constexpr bool operator==(const T& l, const uapprox& r) { + return approx(l, r.value, uapprox_epsilon_v); } template < typename T > - constexpr bool operator==(const vec& l, const approx2& r) { - return all(equal_to(l, r.value, approx_epsilon_v)); + constexpr bool operator==(const vec& l, const uapprox2& r) { + return all(approx(l, r.value, uapprox_epsilon_v)); } template < typename T > - constexpr bool operator==(const vec& l, const approx3& r) { - return all(equal_to(l, r.value, approx_epsilon_v)); + constexpr bool operator==(const vec& l, const uapprox3& r) { + return all(approx(l, r.value, uapprox_epsilon_v)); } template < typename T > - constexpr bool operator==(const vec& l, const approx4& r) { - return all(equal_to(l, r.value, approx_epsilon_v)); + constexpr bool operator==(const vec& l, const uapprox4& r) { + return all(approx(l, r.value, uapprox_epsilon_v)); } } diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index f5f256a..de4bf97 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -42,21 +42,38 @@ TEST_CASE("vmath/vec_fun") { SUBCASE("Operators") { STATIC_REQUIRE(-int2(1,-2) == int2(-1,2)); + STATIC_REQUIRE(~uint2(0xF0F0F0F0,0x0F0F0F0F) == uint2(0x0F0F0F0F,0xF0F0F0F0)); + STATIC_REQUIRE(!int3(-1,0,1) == bool3(false, true, false)); STATIC_REQUIRE(int2(1,2) + 3 == int2(4,5)); STATIC_REQUIRE(int2(1,2) - 3 == int2(-2,-1)); STATIC_REQUIRE(int2(1,2) * 3 == int2(3,6)); STATIC_REQUIRE(int2(2,4) / 2 == int2(1,2)); + STATIC_REQUIRE((int2(11,12) & 6) == int2(2,4)); + STATIC_REQUIRE((int2(11,12) | 6) == int2(15,14)); + STATIC_REQUIRE((int2(11,12) ^ 6) == int2(13,10)); + STATIC_REQUIRE((int2(1,0) && 1) == bool2(1,0)); + STATIC_REQUIRE((int2(1,0) || 1) == bool2(1,1)); STATIC_REQUIRE(3 + int2(1,2) == int2(4,5)); STATIC_REQUIRE(3 - int2(1,2) == int2(2,1)); STATIC_REQUIRE(3 * int2(1,2) == int2(3,6)); STATIC_REQUIRE(4 / int2(2,4) == int2(2,1)); + STATIC_REQUIRE((6 & int2(11,12)) == int2(2,4)); + STATIC_REQUIRE((6 | int2(11,12)) == int2(15,14)); + STATIC_REQUIRE((6 ^ int2(11,12)) == int2(13,10)); + STATIC_REQUIRE((1 && int2(1,0)) == bool2(1,0)); + STATIC_REQUIRE((1 || int2(1,0)) == bool2(1,1)); STATIC_REQUIRE(int2(1,2) + int2(3,4) == int2(4,6)); STATIC_REQUIRE(int2(1,2) - int2(3,4) == int2(-2,-2)); STATIC_REQUIRE(int2(1,2) * int2(3,4) == int2(3,8)); STATIC_REQUIRE(int2(3,4) / int2(1,2) == int2(3,2)); + STATIC_REQUIRE((int2(6,7) & int2(11,12)) == int2(2,4)); + STATIC_REQUIRE((int2(6,7) | int2(11,12)) == int2(15,15)); + STATIC_REQUIRE((int2(6,7) ^ int2(11,12)) == int2(13,11)); + STATIC_REQUIRE((int2(0,1) && int2(1,0)) == bool2(0,0)); + STATIC_REQUIRE((int2(0,1) || int2(1,0)) == bool2(1,1)); { int2 v{1,2}; @@ -86,11 +103,35 @@ TEST_CASE("vmath/vec_fun") { REQUIRE(&v == &(v /= int2{3,4})); REQUIRE(v == int2{1,2}); } + { + int2 v1{11,12}; + REQUIRE(&v1 == &(v1 &= 6)); + REQUIRE(v1 == int2(2,4)); + int2 v2{6,7}; + REQUIRE(&v2 == &(v2 &= int2(11,12))); + REQUIRE(v2 == int2(2,4)); + } + { + int2 v1{11,12}; + REQUIRE(&v1 == &(v1 |= 6)); + REQUIRE(v1 == int2(15,14)); + int2 v2{6,7}; + REQUIRE(&v2 == &(v2 |= int2(11,12))); + REQUIRE(v2 == int2(15,15)); + } + { + int2 v1{11,12}; + REQUIRE(&v1 == &(v1 ^= 6)); + REQUIRE(v1 == int2(13,10)); + int2 v2{6,7}; + REQUIRE(&v2 == &(v2 ^= int2(11,12))); + REQUIRE(v2 == int2(13,11)); + } } SUBCASE("Angle and Trigonometry Functions") { - STATIC_REQUIRE(radians(degrees(float2(12.13f))) == approx2(12.13f)); - STATIC_REQUIRE(degrees(radians(float2(12.13f))) == approx2(12.13f)); + STATIC_REQUIRE(radians(degrees(float2(12.13f))) == uapprox2(12.13f)); + STATIC_REQUIRE(degrees(radians(float2(12.13f))) == uapprox2(12.13f)); (void)sin(float2(1.f)); (void)cos(float2(1.f)); @@ -112,8 +153,8 @@ TEST_CASE("vmath/vec_fun") { { float2 out_ss{}, out_cs{}; sincos(float2(10.f,15.f), &out_ss, &out_cs); - REQUIRE(out_ss == approx2(sin(10.f), sin(15.f))); - REQUIRE(out_cs == approx2(cos(10.f), cos(15.f))); + REQUIRE(out_ss == uapprox2(sin(10.f), sin(15.f))); + REQUIRE(out_cs == uapprox2(cos(10.f), cos(15.f))); } } @@ -128,9 +169,9 @@ TEST_CASE("vmath/vec_fun") { } SUBCASE("Common Functions") { - 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)); - STATIC_REQUIRE(reciprocal(float2(2.f, 4.f)) == approx2(0.5f,0.25f)); + STATIC_REQUIRE(abs(float2(1.f, -1.f)) == uapprox2(1.f,1.f)); + STATIC_REQUIRE(sign(float3(1.f, -1.f, 0.f)) == uapprox3(1.f,-1.f,0.f)); + STATIC_REQUIRE(rcp(float2(2.f, 4.f)) == uapprox2(0.5f,0.25f)); (void)floor(float2(1.f, -1.f)); (void)trunc(float2(1.f, -1.f)); @@ -138,13 +179,13 @@ TEST_CASE("vmath/vec_fun") { (void)ceil(float2(1.f, -1.f)); (void)fract(float2(1.f, -1.f)); - REQUIRE(fmod(float2(1.7f), 1.2f) == approx2(0.5f)); - REQUIRE(fmod(float2(1.7f), float2(1.2f)) == approx2(0.5f)); + REQUIRE(fmod(float2(1.7f), 1.2f) == uapprox2(0.5f)); + REQUIRE(fmod(float2(1.7f), float2(1.2f)) == uapprox2(0.5f)); { float2 out_i{}; - REQUIRE(modf(float2(1.7f), &out_i) == approx2(0.7f)); - REQUIRE(out_i.x == approx(1.f)); + REQUIRE(modf(float2(1.7f), &out_i) == uapprox2(0.7f)); + REQUIRE(out_i.x == uapprox(1.f)); } STATIC_REQUIRE(min(int2(1,2)) == 1); @@ -158,74 +199,58 @@ TEST_CASE("vmath/vec_fun") { STATIC_REQUIRE(clamp(int2(1,2), 0, 1) == int2(1,1)); STATIC_REQUIRE(clamp(int2(1,2), int2(0), int2(1)) == int2(1,1)); - STATIC_REQUIRE(saturate(float3(-1.f,0.5,1.5f)) == approx3(0.f,0.5f,1.f)); + STATIC_REQUIRE(saturate(float3(-1.f,0.5,1.5f)) == uapprox3(0.f,0.5f,1.f)); - STATIC_REQUIRE(lerp(float2(0.f), float2(10.f), 0.5f) == approx2(5.f)); - STATIC_REQUIRE(lerp(float2(0.f), float2(10.f), float2(0.5f)) == approx2(5.f)); + STATIC_REQUIRE(lerp(float2(0.f), float2(10.f), 0.5f) == uapprox2(5.f)); + STATIC_REQUIRE(lerp(float2(0.f), float2(10.f), float2(0.5f)) == uapprox2(5.f)); - STATIC_REQUIRE(step(0.5f, float2(0.4f)) == approx2(0.f)); - STATIC_REQUIRE(step(0.5f, float2(0.6f)) == approx2(1.f)); - STATIC_REQUIRE(step(float2(0.5f), float2(0.4f)) == approx2(0.f)); - STATIC_REQUIRE(step(float2(0.5f), float2(0.6f)) == approx2(1.f)); + STATIC_REQUIRE(step(0.5f, float2(0.4f)) == uapprox2(0.f)); + STATIC_REQUIRE(step(0.5f, float2(0.6f)) == uapprox2(1.f)); + STATIC_REQUIRE(step(float2(0.5f), float2(0.4f)) == uapprox2(0.f)); + STATIC_REQUIRE(step(float2(0.5f), float2(0.6f)) == uapprox2(1.f)); - STATIC_REQUIRE(smoothstep(0.f, 1.f, float2(0.1f)) == approx2(0.028f)); - STATIC_REQUIRE(smoothstep(float2(0.f), float2(1.f), float2(0.1f)) == approx2(0.028f)); + STATIC_REQUIRE(smoothstep(0.f, 1.f, float2(0.1f)) == uapprox2(0.028f)); + STATIC_REQUIRE(smoothstep(float2(0.f), float2(1.f), float2(0.1f)) == uapprox2(0.028f)); REQUIRE_FALSE(isnan(float2(1.f)).x); REQUIRE_FALSE(isinf(float2(1.f)).x); REQUIRE(isfinite(float2(1.f)).x); - REQUIRE_FALSE(fma(float2(2.f), float2(3.f), float2(4.f)).x == approx(12.f)); + REQUIRE_FALSE(fma(float2(2.f), float2(3.f), float2(4.f)).x == uapprox(12.f)); { int2 out_exp{}; - REQUIRE(frexp(float2(1.7f), &out_exp).x == approx(0.85f)); + REQUIRE(frexp(float2(1.7f), &out_exp).x == uapprox(0.85f)); REQUIRE(out_exp == int2(1)); } - REQUIRE(ldexp(float2(0.85f), int2(1)).x == approx(1.7f)); + REQUIRE(ldexp(float2(0.85f), int2(1)).x == uapprox(1.7f)); } SUBCASE("Geometric Functions") { - REQUIRE(length(float2(10.f,0.f)) == approx(10.f)); - REQUIRE(length(float2(-10.f,0.f)) == approx(10.f)); + REQUIRE(length(float2(10.f,0.f)) == uapprox(10.f)); + REQUIRE(length(float2(-10.f,0.f)) == uapprox(10.f)); - STATIC_REQUIRE(length2(float2(10.f,0.f)) == approx(100.f)); - STATIC_REQUIRE(length2(float2(-10.f,0.f)) == approx(100.f)); + STATIC_REQUIRE(length2(float2(10.f,0.f)) == uapprox(100.f)); + STATIC_REQUIRE(length2(float2(-10.f,0.f)) == uapprox(100.f)); - REQUIRE(distance(float2(5.f,0.f), float2(10.f,0.f)) == approx(5.f)); - REQUIRE(distance(float2(-5.f,0.f), float2(-10.f,0.f)) == approx(5.f)); + REQUIRE(distance(float2(5.f,0.f), float2(10.f,0.f)) == uapprox(5.f)); + REQUIRE(distance(float2(-5.f,0.f), float2(-10.f,0.f)) == uapprox(5.f)); - STATIC_REQUIRE(distance2(float2(5.f,0.f), float2(10.f,0.f)) == approx(25.f)); - STATIC_REQUIRE(distance2(float2(-5.f,0.f), float2(-10.f,0.f)) == approx(25.f)); + STATIC_REQUIRE(distance2(float2(5.f,0.f), float2(10.f,0.f)) == uapprox(25.f)); + STATIC_REQUIRE(distance2(float2(-5.f,0.f), float2(-10.f,0.f)) == uapprox(25.f)); STATIC_REQUIRE(dot(int2(1,2),int2(3,4)) == 11); STATIC_REQUIRE(cross(int2(1,0),int2(0,1)) == 1); STATIC_REQUIRE(cross(int3(1,0,0),int3(0,1,0)) == int3(0,0,1)); - REQUIRE(normalize(float2(0.5f,0.f)).x == approx(1.f)); + REQUIRE(normalize(float2(0.5f,0.f)).x == uapprox(1.f)); - STATIC_REQUIRE(faceforward(float2(1.f), float2(2.f), float2(3.f)).x == approx(-1.f)); - STATIC_REQUIRE(reflect(float2(1.f), float2(2.f)).x == approx(-15.f)); - REQUIRE(refract(float2(1.f), float2(2.f), 1.f).x == approx(-15.f)); + STATIC_REQUIRE(faceforward(float2(1.f), float2(2.f), float2(3.f)).x == uapprox(-1.f)); + STATIC_REQUIRE(reflect(float2(1.f), float2(2.f)).x == uapprox(-15.f)); + REQUIRE(refract(float2(1.f), float2(2.f), 1.f).x == uapprox(-15.f)); } - SUBCASE("Vector Relational Functions") { - STATIC_REQUIRE(less(int3(1,1,1), int3(0,1,2)) == bool3(false, false, true)); - STATIC_REQUIRE(less_equal(int3(1,1,1), int3(0,1,2)) == bool3(false, true, true)); - - STATIC_REQUIRE(greater(int3(1,1,1), int3(0,1,2)) == bool3(true, false, false)); - STATIC_REQUIRE(greater_equal(int3(1,1,1), int3(0,1,2)) == bool3(true, true, false)); - - STATIC_REQUIRE(equal_to(int3(1,1,1), int3(0,1,2)) == bool3(false, true, false)); - STATIC_REQUIRE(equal_to(int4(1,1,1,1), int4(0,1,2,3), 0) == bool4(false, true, false, false)); - STATIC_REQUIRE(equal_to(int4(1,1,1,1), int4(0,1,2,3), 1) == bool4(true, true, true, false)); - STATIC_REQUIRE(equal_to(int4(1,1,1,1), int4(0,1,2,3), 2) == bool4(true, true, true, true)); - - STATIC_REQUIRE(not_equal_to(int3(1,1,1), int3(0,1,2)) == bool3(true, false, true)); - STATIC_REQUIRE(not_equal_to(int4(1,1,1,1), int4(0,1,2,3), 0) == bool4(true, false, true, true)); - STATIC_REQUIRE(not_equal_to(int4(1,1,1,1), int4(0,1,2,3), 1) == bool4(false, false, false, true)); - STATIC_REQUIRE(not_equal_to(int4(1,1,1,1), int4(0,1,2,3), 2) == bool4(false, false, false, false)); - + SUBCASE("Relational Functions") { STATIC_REQUIRE_FALSE(any(bool2(false, false))); STATIC_REQUIRE(any(bool2(true, false))); STATIC_REQUIRE(any(bool2(false, true))); @@ -245,5 +270,45 @@ TEST_CASE("vmath/vec_fun") { STATIC_REQUIRE_FALSE(all(int2(1, 0))); STATIC_REQUIRE_FALSE(all(int2(0, 1))); STATIC_REQUIRE(all(int2(1, 1))); + + STATIC_REQUIRE(approx(int3(1,1,1), int3(0,1,2)) == bool3(false, true, false)); + STATIC_REQUIRE(approx(int3(0,1,2),1) == bool3(false, true, false)); + STATIC_REQUIRE(approx(1,int3(0,1,2)) == bool3(false, true, false)); + + STATIC_REQUIRE(approx(int4(1,1,1,1), int4(0,1,2,3), 0) == bool4(false, true, false, false)); + STATIC_REQUIRE(approx(int4(0,1,2,3), 1, 0) == bool4(false, true, false, false)); + STATIC_REQUIRE(approx(1, int4(0,1,2,3), 0) == bool4(false, true, false, false)); + + STATIC_REQUIRE(approx(int4(1,1,1,1), int4(0,1,2,3), 1) == bool4(true, true, true, false)); + STATIC_REQUIRE(approx(int4(0,1,2,3), 1, 1) == bool4(true, true, true, false)); + STATIC_REQUIRE(approx(1, int4(0,1,2,3), 1) == bool4(true, true, true, false)); + + STATIC_REQUIRE(approx(int4(1,1,1,1), int4(0,1,2,3), 2) == bool4(true, true, true, true)); + STATIC_REQUIRE(approx(int4(0,1,2,3), 1, 2) == bool4(true, true, true, true)); + STATIC_REQUIRE(approx(1, int4(0,1,2,3), 2) == bool4(true, true, true, true)); + + STATIC_REQUIRE(less(int3(1,1,1), int3(0,1,2)) == bool3(false, false, true)); + STATIC_REQUIRE(less(int3(0,1,2), 1) == bool3(true, false, false)); + STATIC_REQUIRE(less(1, int3(0,1,2)) == bool3(false, false, true)); + + STATIC_REQUIRE(less_equal(int3(1,1,1), int3(0,1,2)) == bool3(false, true, true)); + STATIC_REQUIRE(less_equal(int3(0,1,2), 1) == bool3(true, true, false)); + STATIC_REQUIRE(less_equal(1, int3(0,1,2)) == bool3(false, true, true)); + + STATIC_REQUIRE(greater(int3(1,1,1), int3(0,1,2)) == bool3(true, false, false)); + STATIC_REQUIRE(greater(int3(0,1,2), 1) == bool3(false, false, true)); + STATIC_REQUIRE(greater(1, int3(0,1,2)) == bool3(true, false, false)); + + STATIC_REQUIRE(greater_equal(int3(1,1,1), int3(0,1,2)) == bool3(true, true, false)); + STATIC_REQUIRE(greater_equal(int3(0,1,2), 1) == bool3(false, true, true)); + STATIC_REQUIRE(greater_equal(1, int3(0,1,2)) == bool3(true, true, false)); + + STATIC_REQUIRE(equal_to(int3(1,1,1), int3(0,1,2)) == bool3(false, true, false)); + STATIC_REQUIRE(equal_to(int3(0,1,2),1) == bool3(false, true, false)); + STATIC_REQUIRE(equal_to(1,int3(0,1,2)) == bool3(false, true, false)); + + STATIC_REQUIRE(not_equal_to(int3(1,1,1), int3(0,1,2)) == bool3(true, false, true)); + STATIC_REQUIRE(not_equal_to(int3(0,1,2),1) == bool3(true, false, true)); + STATIC_REQUIRE(not_equal_to(1,int3(0,1,2)) == bool3(true, false, true)); } }