From 38161f01f81fd6cfa4e901c8fd54d6126c0ba39e Mon Sep 17 00:00:00 2001 From: Christophe Riccio Date: Fri, 21 Nov 2014 23:43:48 +0100 Subject: [PATCH] Further optimized glm::sign for signed and unsigned int #271 --- glm/detail/func_common.inl | 36 ++++++++++++++++++++++++++++++++-- readme.txt | 1 + test/core/core_func_common.cpp | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/glm/detail/func_common.inl b/glm/detail/func_common.inl index 6d021e2b..150bdb14 100644 --- a/glm/detail/func_common.inl +++ b/glm/detail/func_common.inl @@ -128,6 +128,36 @@ namespace detail return a ? y : x; } }; + + template class vecType, bool isFloat = true, bool isSigned = true> + struct compute_sign + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return vecType(glm::lessThan(vecType(0), x)) - vecType(glm::lessThan(x, vecType(0))); + } + }; + + template class vecType> + struct compute_sign + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + return glm::abs(x); + } + }; + + template class vecType> + struct compute_sign + { + GLM_FUNC_QUALIFIER static vecType call(vecType const & x) + { + T const Shift(static_cast(sizeof(T) * 8 - 1)); + vecType const y(vecType::type, P>(-x) >> typename make_unsigned::type(Shift)); + + return (x >> Shift) | y; + } + }; }//namespace detail // abs @@ -159,7 +189,7 @@ namespace detail std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), "'sign' only accept signed inputs"); - return static_cast(static_cast(0) < x) - static_cast(x < static_cast(0)); + return detail::compute_sign::is_iec559>::call(tvec1(x)).x; } template class vecType> @@ -169,7 +199,9 @@ namespace detail std::numeric_limits::is_iec559 || (std::numeric_limits::is_signed && std::numeric_limits::is_integer), "'sign' only accept signed inputs"); - return vecType(glm::lessThan(vecType(0), x)) - vecType(glm::lessThan(x, vecType(0))); + return detail::compute_sign::is_iec559>::call(x); + + //return vecType(glm::lessThan(vecType(0), x)) - vecType(glm::lessThan(x, vecType(0))); } // floor diff --git a/readme.txt b/readme.txt index db596fb5..26b7c1fe 100644 --- a/readme.txt +++ b/readme.txt @@ -76,6 +76,7 @@ Improvements: - Removed in GLM tests - Used std features within GLM without redeclaring - Optimized glm::cot #272 +- Optimized glm::sign #272 Fixes: - Fixed std::nextafter not supported with C++11 on Android #217 diff --git a/test/core/core_func_common.cpp b/test/core/core_func_common.cpp index eea1e61e..3ed22cc1 100644 --- a/test/core/core_func_common.cpp +++ b/test/core/core_func_common.cpp @@ -844,6 +844,8 @@ namespace sign { type const Data[] = { + { std::numeric_limits::max(), 1}, + { std::numeric_limits::min(), -1}, { 0, 0}, { 1, 1}, { 2, 1},