Browse Source

Added log2 for int types

Christophe Riccio 14 years ago
parent
commit
16ef34f9c5
5 changed files with 124 additions and 17 deletions
  1. 85 0
      glm/core/_detail.hpp
  2. 25 3
      glm/core/func_exponential.inl
  3. 1 0
      glm/glm.hpp
  4. 2 1
      glm/gtx/integer.hpp
  5. 11 13
      glm/gtx/integer.inl

+ 85 - 0
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 <typename T>
+	struct float_or_int_trait
+	{
+		enum{ID = float_or_int_value::ERROR};
+	};
+
+	template <>
+	struct float_or_int_trait<int8>
+	{
+		enum{ID = float_or_int_value::INT};
+	};
+
+	template <>
+	struct float_or_int_trait<int16>
+	{
+		enum{ID = float_or_int_value::INT};
+	};
+
+	template <>
+	struct float_or_int_trait<int32>
+	{
+		enum{ID = float_or_int_value::INT};
+	};
+
+	template <>
+	struct float_or_int_trait<int64>
+	{
+		enum{ID = float_or_int_value::INT};
+	};
+
+	template <>
+	struct float_or_int_trait<uint8>
+	{
+		enum{ID = float_or_int_value::INT};
+	};
+
+	template <>
+	struct float_or_int_trait<uint16>
+	{
+		enum{ID = float_or_int_value::INT};
+	};
+
+	template <>
+	struct float_or_int_trait<uint32>
+	{
+		enum{ID = float_or_int_value::INT};
+	};
+
+	template <>
+	struct float_or_int_trait<uint64>
+	{
+		enum{ID = float_or_int_value::INT};
+	};
+
+	template <>
+	struct float_or_int_trait<float16>
+	{
+		enum{ID = float_or_int_value::FLOAT};
+	};
+
+	template <>
+	struct float_or_int_trait<float32>
+	{
+		enum{ID = float_or_int_value::FLOAT};
+	};
+
+	template <>
+	struct float_or_int_trait<float64>
+	{
+		enum{ID = float_or_int_value::FLOAT};
+	};
+
 }//namespace detail
 
 }//namespace glm

+ 25 - 3
glm/core/func_exponential.inl

@@ -224,6 +224,30 @@ namespace glm
             exp2(x.w));
     }
 
+namespace detail
+{
+	template <int PATH = float_or_int_value::ERROR>
+	struct compute_log2
+	{
+		template <typename T>
+		T operator() (T const & Value) const
+		{
+			static_assert(0, "'log2' parameter has an invalid template parameter type");
+			return Value;
+		}
+	};
+
+	template <>
+	struct compute_log2<float_or_int_value::FLOAT>
+	{
+		template <typename T>
+		T operator() (T const & Value) const
+		{
+			return ::std::log(Value) / T(0.69314718055994530941723212145818);
+		}
+	};
+}//namespace detail
+
     // log2, ln2 = 0.69314718055994530941723212145818f
     template <typename genType>
     GLM_FUNC_QUALIFIER genType log2
@@ -231,9 +255,7 @@ namespace glm
 		genType const & x
 	)
     {
-		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'log2' only accept floating-point input");
-
-        return ::std::log(x) / genType(0.69314718055994530941723212145818);
+		return detail::compute_log2<detail::float_or_int_trait<genType>::ID>()(x);
     }
 
     template <typename T>

+ 1 - 0
glm/glm.hpp

@@ -84,6 +84,7 @@
 #include <climits>
 #include <cfloat>
 #include <limits>
+#include <type_traits>
 #include "core/setup.hpp"
 
 #if(defined(GLM_MESSAGES) && !defined(GLM_MESSAGE_CORE_INCLUDED_DISPLAYED))

+ 2 - 1
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 <typename genType>
+	genType log2(genType const & x);
 
 	//! Returns the floor log2 of x.
 	//! From GLM_GTX_integer extension.

+ 11 - 13
glm/gtx/integer.inl

@@ -53,23 +53,21 @@ namespace detail
 		x += (x >> 16);
 		return(x & 0x0000003f);
 	}
-}//namespace detail
 
+	template <>
+	struct compute_log2<float_or_int_value::INT>
+	{
+		template <typename T>
+		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)