diff --git a/glm/core/_detail.hpp b/glm/core/_detail.hpp index e6d2e128..ce933aa0 100644 --- a/glm/core/_detail.hpp +++ b/glm/core/_detail.hpp @@ -345,6 +345,91 @@ namespace detail typedef float float32; typedef double float64; + ////////////////// + // float_or_int_trait + + struct float_or_int_value + { + enum + { + ERROR, + FLOAT, + INT + }; + }; + + template + struct float_or_int_trait + { + enum{ID = float_or_int_value::ERROR}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::INT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::INT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::INT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::INT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::INT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::INT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::INT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::INT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::FLOAT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::FLOAT}; + }; + + template <> + struct float_or_int_trait + { + enum{ID = float_or_int_value::FLOAT}; + }; + }//namespace detail }//namespace glm diff --git a/glm/core/func_exponential.inl b/glm/core/func_exponential.inl index c8c385f7..c1ffee92 100644 --- a/glm/core/func_exponential.inl +++ b/glm/core/func_exponential.inl @@ -224,6 +224,30 @@ namespace glm exp2(x.w)); } +namespace detail +{ + template + struct compute_log2 + { + template + T operator() (T const & Value) const + { + static_assert(0, "'log2' parameter has an invalid template parameter type"); + return Value; + } + }; + + template <> + struct compute_log2 + { + template + T operator() (T const & Value) const + { + return ::std::log(Value) / T(0.69314718055994530941723212145818); + } + }; +}//namespace detail + // log2, ln2 = 0.69314718055994530941723212145818f template GLM_FUNC_QUALIFIER genType log2 @@ -231,9 +255,7 @@ namespace glm genType const & x ) { - GLM_STATIC_ASSERT(detail::type::is_float, "'log2' only accept floating-point input"); - - return ::std::log(x) / genType(0.69314718055994530941723212145818); + return detail::compute_log2::ID>()(x); } template diff --git a/glm/glm.hpp b/glm/glm.hpp index 7380a718..79e1d878 100644 --- a/glm/glm.hpp +++ b/glm/glm.hpp @@ -84,6 +84,7 @@ #include #include #include +#include #include "core/setup.hpp" #if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_CORE_INCLUDED_DISPLAYED)) diff --git a/glm/gtx/integer.hpp b/glm/gtx/integer.hpp index 9369bd43..7d374098 100644 --- a/glm/gtx/integer.hpp +++ b/glm/gtx/integer.hpp @@ -60,7 +60,8 @@ namespace glm //! Returns the log2 of x. Can be reliably using to compute mipmap count from the texture size. //! From GLM_GTX_integer extension. - unsigned int log2(unsigned int x); + template + genType log2(genType const & x); //! Returns the floor log2 of x. //! From GLM_GTX_integer extension. diff --git a/glm/gtx/integer.inl b/glm/gtx/integer.inl index 8c883728..870887a7 100644 --- a/glm/gtx/integer.inl +++ b/glm/gtx/integer.inl @@ -53,23 +53,21 @@ namespace detail x += (x >> 16); return(x & 0x0000003f); } -}//namespace detail + template <> + struct compute_log2 + { + template + T operator() (T const & Value) const + { #if(GLM_COMPILER & (GLM_COMPILER_VC | GLM_COMPILER_GCC)) - -GLM_FUNC_QUALIFIER unsigned int log2(unsigned int x) -{ - return x <= 1 ? 0 : unsigned(32) - nlz(x - 1u); -} - + return Value <= T(1) ? T(0) : T(32) - nlz(Value - T(1)); #else - -GLM_FUNC_QUALIFIER unsigned int log2(unsigned int x) -{ - return unsigned(32) - nlz(x - 1u); -} - + return T(32) - nlz(Value - T(1)); #endif + } + }; +}//namespace detail // Henry Gordon Dietz: http://aggregate.org/MAGIC/ unsigned int floor_log2(unsigned int x)