diff --git a/README.md b/README.md index cbb55a8..e6bb118 100644 --- a/README.md +++ b/README.md @@ -373,6 +373,11 @@ using ptrdiff4x4 = mat; template < typename T, size_t Size > constexpr vec operator-(const vec& xs); +// !operator + +template < typename T, std::size_t Size > +constexpr vec operator!(const vec& xs); + // operator+ template < typename T, size_t Size > @@ -471,6 +476,11 @@ 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 > @@ -569,9 +579,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; @@ -622,9 +632,11 @@ std::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 +688,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 +711,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 +740,9 @@ vec rsqrt(const vec& xs); ### Common Functions -```cpp -// Scalar +#### Scalar +```cpp template < arithmetic T > constexpr T abs(T x) noexcept; @@ -803,9 +817,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); @@ -905,9 +921,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 +950,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,9 +991,9 @@ vec refract(const vec& i, const vec& n, T eta); ### Relational Functions -```cpp -// Scalar +#### Scalar +```cpp template < arithmetic T > constexpr bool less(T x, T y) noexcept; @@ -1005,31 +1023,81 @@ constexpr bool any(T x) noexcept; template < arithmetic T > constexpr bool all(T x) noexcept; +``` -// Vector +#### Vector -template < typename T, size_t Size > +```cpp +template < typename T, std::size_t Size > +constexpr vec less(const vec& xs, T y); + +template < typename T, std::size_t Size > +constexpr vec less(T x, const vec& ys); + +template < typename T, std::size_t Size > constexpr vec less(const vec& xs, const vec& ys); -template < typename T, size_t Size > +template < typename T, std::size_t Size > +constexpr vec less_equal(const vec& xs, T y); + +template < typename T, std::size_t Size > +constexpr vec less_equal(T x, const vec& ys); + +template < typename T, std::size_t Size > constexpr vec less_equal(const vec& xs, const vec& ys); -template < typename T, size_t Size > +template < typename T, std::size_t Size > +constexpr vec greater(const vec& xs, T y); + +template < typename T, std::size_t Size > +constexpr vec greater(T x, const vec& ys); + +template < typename T, std::size_t Size > constexpr vec greater(const vec& xs, const vec& ys); -template < typename T, size_t Size > +template < typename T, std::size_t Size > +constexpr vec greater_equal(const vec& xs, T y); + +template < typename T, std::size_t Size > +constexpr vec greater_equal(T x, const vec& ys); + +template < typename T, std::size_t Size > constexpr vec greater_equal(const vec& xs, const vec& ys); -template < typename T, size_t Size > +template < typename T, std::size_t Size > +constexpr vec equal_to(const vec& xs, T y); + +template < typename T, std::size_t Size > +constexpr vec equal_to(T x, const vec& ys); + +template < typename T, std::size_t Size > constexpr vec equal_to(const vec& xs, const vec& ys); -template < typename T, size_t Size > +template < typename T, std::size_t Size > +constexpr vec equal_to(const vec& xs, T y, T epsilon); + +template < typename T, std::size_t Size > +constexpr vec equal_to(T x, const vec& ys, T epsilon); + +template < typename T, std::size_t Size > constexpr vec equal_to(const vec& xs, const vec& ys, T epsilon); -template < typename T, size_t Size > +template < typename T, std::size_t Size > +constexpr vec not_equal_to(const vec& xs, T y); + +template < typename T, std::size_t Size > +constexpr vec not_equal_to(T x, const vec& ys); + +template < typename T, std::size_t Size > constexpr vec not_equal_to(const vec& xs, const vec& ys); -template < typename T, size_t Size > +template < typename T, std::size_t Size > +constexpr vec not_equal_to(const vec& xs, T y, T epsilon); + +template < typename T, std::size_t Size > +constexpr vec not_equal_to(T x, const vec& ys, T epsilon); + +template < typename T, std::size_t Size > constexpr vec not_equal_to(const vec& xs, const vec& ys, T epsilon); template < typename T, size_t Size > @@ -1192,8 +1260,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); diff --git a/headers/vmath.hpp/vmath_mat_fun.hpp b/headers/vmath.hpp/vmath_mat_fun.hpp index 8ffc74e..d9013ff 100644 --- a/headers/vmath.hpp/vmath_mat_fun.hpp +++ b/headers/vmath.hpp/vmath_mat_fun.hpp @@ -199,6 +199,13 @@ 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 > diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index d9a0cf0..7e6bb00 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -172,6 +172,13 @@ 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 > @@ -708,46 +715,140 @@ namespace vmath_hpp namespace vmath_hpp { + // 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); } + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec equal_to(const vec& xs, T y, T epsilon) { + return map_join([y, epsilon](T x){ return equal_to(x, y, epsilon); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec equal_to(T x, const vec& ys, T epsilon) { + return map_join([x, epsilon](T y){ return equal_to(x, y, epsilon); }, ys); + } + 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); } + // not_equal_to + + template < typename T, std::size_t Size > + [[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, T y, T epsilon) { + return map_join([y, epsilon](T x){ return not_equal_to(x, y, epsilon); }, xs); + } + + template < typename T, std::size_t Size > + [[nodiscard]] constexpr vec not_equal_to(T x, const vec& ys, T epsilon) { + return map_join([x, epsilon](T y){ return not_equal_to(x, y, epsilon); }, 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); } + // any/all + 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); diff --git a/untests/vmath_mat_fun_tests.cpp b/untests/vmath_mat_fun_tests.cpp index c8b7069..6ceeac9 100644 --- a/untests/vmath_mat_fun_tests.cpp +++ b/untests/vmath_mat_fun_tests.cpp @@ -59,6 +59,7 @@ TEST_CASE("vmath/mat_fun") { SUBCASE("operators") { STATIC_REQUIRE(-int2x2(1,2,3,4) == int2x2(-1,-2,-3,-4)); + 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)); diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index f5f256a..ba1a79d 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -42,6 +42,7 @@ TEST_CASE("vmath/vec_fun") { SUBCASE("Operators") { STATIC_REQUIRE(-int2(1,-2) == int2(-1,2)); + 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)); @@ -211,20 +212,52 @@ TEST_CASE("vmath/vec_fun") { SUBCASE("Vector Relational Functions") { 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(equal_to(int4(1,1,1,1), int4(0,1,2,3), 0) == bool4(false, true, false, false)); + STATIC_REQUIRE(equal_to(int4(0,1,2,3), 1, 0) == bool4(false, true, false, false)); + STATIC_REQUIRE(equal_to(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(0,1,2,3), 1, 1) == bool4(true, true, true, false)); + STATIC_REQUIRE(equal_to(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(equal_to(int4(0,1,2,3), 1, 2) == bool4(true, true, true, true)); + STATIC_REQUIRE(equal_to(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(int3(0,1,2),1) == bool3(true, false, true)); + STATIC_REQUIRE(not_equal_to(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(0,1,2,3), 1, 0) == bool4(true, false, true, true)); + STATIC_REQUIRE(not_equal_to(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(0,1,2,3), 1, 1) == bool4(false, false, false, true)); + STATIC_REQUIRE(not_equal_to(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)); + STATIC_REQUIRE(not_equal_to(int4(0,1,2,3), 1, 2) == bool4(false, false, false, false)); + STATIC_REQUIRE(not_equal_to(1, int4(0,1,2,3), 2) == bool4(false, false, false, false)); STATIC_REQUIRE_FALSE(any(bool2(false, false))); STATIC_REQUIRE(any(bool2(true, false)));