diff --git a/headers/vmath.hpp/vmath_ext.hpp b/headers/vmath.hpp/vmath_ext.hpp index 76e9d76..e13f97d 100644 --- a/headers/vmath.hpp/vmath_ext.hpp +++ b/headers/vmath.hpp/vmath_ext.hpp @@ -510,7 +510,7 @@ namespace vmath_hpp template < typename T, std::size_t Size > T angle(const vec& x, const vec& y) { - return acos(dot(x, y) * invsqrt(length2(x) * length2(y))); + return acos(dot(x, y) * rsqrt(length2(x) * length2(y))); } // rotate diff --git a/headers/vmath.hpp/vmath_fun.hpp b/headers/vmath.hpp/vmath_fun.hpp index 8baed1d..5e7e4b3 100644 --- a/headers/vmath.hpp/vmath_fun.hpp +++ b/headers/vmath.hpp/vmath_fun.hpp @@ -15,31 +15,94 @@ namespace vmath_hpp { template < typename T > - constexpr T radians(T degrees) noexcept { + std::enable_if_t, T> + constexpr radians(T degrees) noexcept { return degrees * T(0.01745329251994329576923690768489); } template < typename T > - constexpr T degrees(T radians) noexcept { + std::enable_if_t, T> + constexpr degrees(T radians) noexcept { return radians * T(57.295779513082320876798154814105); } - using ::std::sin; - using ::std::cos; - using ::std::tan; + template < typename T > + std::enable_if_t, T> + sin(T x) noexcept { + return std::sin(x); + } - using ::std::asin; - using ::std::acos; - using ::std::atan; - using ::std::atan2; + template < typename T > + std::enable_if_t, T> + cos(T x) noexcept { + return std::cos(x); + } - using ::std::sinh; - using ::std::cosh; - using ::std::tanh; + template < typename T > + std::enable_if_t, T> + tan(T x) noexcept { + return std::tan(x); + } - using ::std::asinh; - using ::std::acosh; - using ::std::atanh; + template < typename T > + std::enable_if_t, T> + asin(T x) noexcept { + return std::asin(x); + } + + template < typename T > + std::enable_if_t, T> + acos(T x) noexcept { + return std::acos(x); + } + + template < typename T > + std::enable_if_t, T> + atan(T x) noexcept { + return std::atan(x); + } + + template < typename T > + std::enable_if_t, T> + atan2(T y, T x) noexcept { + return std::atan2(y, x); + } + + template < typename T > + std::enable_if_t, T> + sinh(T x) noexcept { + return std::sinh(x); + } + + template < typename T > + std::enable_if_t, T> + cosh(T x) noexcept { + return std::cosh(x); + } + + template < typename T > + std::enable_if_t, T> + tanh(T x) noexcept { + return std::tanh(x); + } + + template < typename T > + std::enable_if_t, T> + asinh(T x) noexcept { + return std::asinh(x); + } + + template < typename T > + std::enable_if_t, T> + acosh(T x) noexcept { + return std::acosh(x); + } + + template < typename T > + std::enable_if_t, T> + atanh(T x) noexcept { + return std::atanh(x); + } } // @@ -48,15 +111,45 @@ namespace vmath_hpp namespace vmath_hpp { - using ::std::pow; - using ::std::exp; - using ::std::log; - using ::std::exp2; - using ::std::log2; - using ::std::sqrt; + template < typename T > + std::enable_if_t, T> + pow(T x, T y) noexcept { + return std::pow(x, y); + } template < typename T > - T invsqrt(T x) noexcept { + std::enable_if_t, T> + exp(T x) noexcept { + return std::exp(x); + } + + template < typename T > + std::enable_if_t, T> + log(T x) noexcept { + return std::log(x); + } + + template < typename T > + std::enable_if_t, T> + exp2(T x) noexcept { + return std::exp2(x); + } + + template < typename T > + std::enable_if_t, T> + log2(T x) noexcept { + return std::log2(x); + } + + template < typename T > + std::enable_if_t, T> + sqrt(T x) noexcept { + return std::sqrt(x); + } + + template < typename T > + std::enable_if_t, T> + rsqrt(T x) noexcept { return T(1) / sqrt(x); } } @@ -80,48 +173,92 @@ namespace vmath_hpp } template < typename T > - constexpr T sign(T x) noexcept { + std::enable_if_t, T> + constexpr sign(T x) noexcept { return static_cast((T(0) < x) - (x < T(0))); } - using ::std::floor; - using ::std::trunc; - using ::std::round; - using ::std::ceil; + template < typename T > + std::enable_if_t, T> + floor(T x) noexcept { + return std::floor(x); + } template < typename T > - T fract(T x) noexcept { + std::enable_if_t, T> + trunc(T x) noexcept { + return std::trunc(x); + } + + template < typename T > + std::enable_if_t, T> + round(T x) noexcept { + return std::round(x); + } + + template < typename T > + std::enable_if_t, T> + ceil(T x) noexcept { + return std::ceil(x); + } + + template < typename T > + std::enable_if_t, T> + fract(T x) noexcept { return x - floor(x); } - using ::std::fmod; - using ::std::modf; - - using ::std::min; - using ::std::max; + template < typename T > + std::enable_if_t, T> + fmod(T x, T y) noexcept { + return std::fmod(x, y); + } template < typename T > - constexpr T clamp(T x, T min_x, T max_x) noexcept { + std::enable_if_t, T> + modf(T x, T* y) noexcept { + return std::modf(x, y); + } + + template < typename T > + std::enable_if_t, T> + constexpr min(T x, T y) noexcept { + return std::min(x, y); + } + + template < typename T > + std::enable_if_t, T> + constexpr max(T x, T y) noexcept { + return std::max(x, y); + } + + template < typename T > + std::enable_if_t, T> + constexpr clamp(T x, T min_x, T max_x) noexcept { return min(max(x, min_x), max_x); } template < typename T > - constexpr T saturate(T x) noexcept { + std::enable_if_t, T> + constexpr saturate(T x) noexcept { return clamp(x, T(0), T(1)); } template < typename T > - constexpr T lerp(T x, T y, T a) noexcept { + std::enable_if_t, T> + constexpr lerp(T x, T y, T a) noexcept { return x * (T(1) - a) + y * a; } template < typename T > - constexpr T step(T edge, T x) noexcept { + std::enable_if_t, T> + constexpr step(T edge, T x) noexcept { return x < edge ? T(0) : T(1); } template < typename T > - constexpr T smoothstep(T edge0, T edge1, T x) noexcept { + std::enable_if_t, T> + constexpr smoothstep(T edge0, T edge1, T x) noexcept { const T t = clamp((x - edge0) / (edge1 - edge0), T(0), T(1)); return t * t * (T(3) - T(2) * t); } @@ -129,16 +266,24 @@ namespace vmath_hpp using ::std::isnan; using ::std::isinf; using ::std::isfinite; - using ::std::isnormal; template < typename T > - bool issubnormal(T x) noexcept { - return std::fpclassify(x) == FP_SUBNORMAL; + std::enable_if_t, T> + fma(T x, T y, T z) noexcept { + return std::fma(x, y, z); } - using ::std::fma; - using ::std::frexp; - using ::std::ldexp; + template < typename T > + std::enable_if_t, T> + frexp(T x, int* exp) noexcept { + return std::frexp(x, exp); + } + + template < typename T > + std::enable_if_t, T> + ldexp(T x, int exp) noexcept { + return std::ldexp(x, exp); + } } // @@ -174,7 +319,7 @@ namespace vmath_hpp template < typename T > T normalize(T x) noexcept { - return x * invsqrt(dot(x, x)); + return x * rsqrt(dot(x, x)); } template < typename T > diff --git a/headers/vmath.hpp/vmath_fwd.hpp b/headers/vmath.hpp/vmath_fwd.hpp index c9e2bad..01f8ea6 100644 --- a/headers/vmath.hpp/vmath_fwd.hpp +++ b/headers/vmath.hpp/vmath_fwd.hpp @@ -6,13 +6,11 @@ #pragma once -#include #include #include #include #include -#include #include #include #include @@ -45,6 +43,10 @@ namespace vmath_hpp using size2 = vec; using size3 = vec; using size4 = vec; + + using ptrdiff2 = vec; + using ptrdiff3 = vec; + using ptrdiff4 = vec; } namespace vmath_hpp @@ -75,4 +77,8 @@ namespace vmath_hpp using size2x2 = mat; using size3x3 = mat; using size4x4 = mat; + + using ptrdiff2x2 = mat; + using ptrdiff3x3 = mat; + using ptrdiff4x4 = mat; } diff --git a/headers/vmath.hpp/vmath_vec_fun.hpp b/headers/vmath.hpp/vmath_vec_fun.hpp index 7700c13..6212191 100644 --- a/headers/vmath.hpp/vmath_vec_fun.hpp +++ b/headers/vmath.hpp/vmath_vec_fun.hpp @@ -370,8 +370,8 @@ namespace vmath_hpp } template < typename T, std::size_t Size > - vec invsqrt(const vec& xs) { - return map([](T x) { return invsqrt(x); }, xs); + vec rsqrt(const vec& xs) { + return map([](T x) { return rsqrt(x); }, xs); } } @@ -529,16 +529,6 @@ namespace vmath_hpp return map([](T x) { return isfinite(x); }, xs); } - template < typename T, std::size_t Size > - vec isnormal(const vec& xs) { - return map([](T x) { return isnormal(x); }, xs); - } - - template < typename T, std::size_t Size > - vec issubnormal(const vec& xs) { - return map([](T x) { return issubnormal(x); }, xs); - } - template < typename T, std::size_t Size > vec fma(const vec& as, const vec& bs, const vec& cs) { return zip([](T a, T b, T c) { return fma(a, b, c); }, as, bs, cs); @@ -611,7 +601,7 @@ namespace vmath_hpp template < typename T, std::size_t Size > vec normalize(const vec& xs) { - return xs * invsqrt(dot(xs, xs)); + return xs * rsqrt(dot(xs, xs)); } template < typename T, std::size_t Size > diff --git a/untests/vmath_fun_tests.cpp b/untests/vmath_fun_tests.cpp index c32ab7b..96c2769 100644 --- a/untests/vmath_fun_tests.cpp +++ b/untests/vmath_fun_tests.cpp @@ -47,7 +47,7 @@ TEST_CASE("vmath/fun") { (void)exp2(2.f); (void)log2(2.f); (void)sqrt(2.f); - (void)invsqrt(2.f); + (void)rsqrt(2.f); } SECTION("Common Functions") { @@ -98,8 +98,6 @@ TEST_CASE("vmath/fun") { REQUIRE_FALSE(isnan(1.f)); REQUIRE_FALSE(isinf(1.f)); REQUIRE(isfinite(1.f)); - REQUIRE(isnormal(1.f)); - REQUIRE_FALSE(issubnormal(1.f)); REQUIRE(fma(2.f, 3.f, 4.f) == approx(10.f)); diff --git a/untests/vmath_vec_fun_tests.cpp b/untests/vmath_vec_fun_tests.cpp index 18584d4..19a574f 100644 --- a/untests/vmath_vec_fun_tests.cpp +++ b/untests/vmath_vec_fun_tests.cpp @@ -95,7 +95,7 @@ TEST_CASE("vmath/vec_fun") { (void)exp2(float2(1.f)); (void)log2(float2(1.f)); (void)sqrt(float2(1.f)); - (void)invsqrt(float2(1.f)); + (void)rsqrt(float2(1.f)); } SECTION("Common Functions") { @@ -144,8 +144,6 @@ TEST_CASE("vmath/vec_fun") { REQUIRE_FALSE(isnan(float2(1.f)).x); REQUIRE_FALSE(isinf(float2(1.f)).x); REQUIRE(isfinite(float2(1.f)).x); - REQUIRE(isnormal(float2(1.f)).x); - REQUIRE_FALSE(issubnormal(float2(1.f)).x); REQUIRE_FALSE(fma(float2(2.f), float2(3.f), float2(4.f)).x == Approx(12.f));