Browse Source

Optimized sign for vector types #271

Christophe Riccio 11 years ago
parent
commit
b0b84a3dc1
2 changed files with 39 additions and 4 deletions
  1. 8 4
      glm/detail/func_common.inl
  2. 31 0
      test/core/core_func_common.cpp

+ 8 - 4
glm/detail/func_common.inl

@@ -156,16 +156,20 @@ namespace detail
 	GLM_FUNC_QUALIFIER genFIType sign(genFIType x)
 	{
 		GLM_STATIC_ASSERT(
-			std::numeric_limits<genFIType>::is_iec559 ||
-			(std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer), "'sign' only accept signed inputs");
+			std::numeric_limits<genFIType>::is_iec559 || (std::numeric_limits<genFIType>::is_signed && std::numeric_limits<genFIType>::is_integer),
+			"'sign' only accept signed inputs");
 		
-		return genFIType(genFIType(0) < x) - (x < genFIType(0));
+		return static_cast<genFIType>(static_cast<genFIType>(0) < x) - static_cast<genFIType>(x < static_cast<genFIType>(0));
 	}
 
 	template <typename T, precision P, template <typename, precision> class vecType>
 	GLM_FUNC_QUALIFIER vecType<T, P> sign(vecType<T, P> const & x)
 	{
-		return detail::functor1<T, T, P, vecType>::call(sign, x);
+		GLM_STATIC_ASSERT(
+			std::numeric_limits<T>::is_iec559 || (std::numeric_limits<T>::is_signed && std::numeric_limits<T>::is_integer),
+			"'sign' only accept signed inputs");
+
+		return vecType<T, P>(glm::lessThan(vecType<T, P>(0), x)) - vecType<T, P>(glm::lessThan(x, vecType<T, P>(0)));
 	}
 
 	// floor

+ 31 - 0
test/core/core_func_common.cpp

@@ -855,6 +855,12 @@ namespace sign
 
 		int Error = 0;
 
+		for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
+		{
+			glm::int32 Result = glm::sign(Data[i].Value);
+			Error += Data[i].Return == Result ? 0 : 1;
+		}
+
 		for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::int32>); ++i)
 		{
 			glm::int32 Result = sign_cmp(Data[i].Value);
@@ -888,11 +894,36 @@ namespace sign
 		return Error;
 	}
 
+	int test_i32vec4()
+	{
+		type<glm::i32vec4> const Data[] =
+		{
+			{glm::i32vec4( 1), glm::i32vec4( 1)},
+			{glm::i32vec4( 0), glm::i32vec4( 0)},
+			{glm::i32vec4( 2), glm::i32vec4( 1)},
+			{glm::i32vec4( 3), glm::i32vec4( 1)},
+			{glm::i32vec4(-1), glm::i32vec4(-1)},
+			{glm::i32vec4(-2), glm::i32vec4(-1)},
+			{glm::i32vec4(-3), glm::i32vec4(-1)}
+		};
+
+		int Error = 0;
+
+		for(std::size_t i = 0; i < sizeof(Data) / sizeof(type<glm::i32vec4>); ++i)
+		{
+			glm::i32vec4 Result = glm::sign(Data[i].Value);
+			Error += glm::all(glm::equal(Data[i].Return, Result)) ? 0 : 1;
+		}
+
+		return Error;
+	}
+
 	int test()
 	{
 		int Error = 0;
 
 		Error += test_int32();
+		Error += test_i32vec4();
 
 		return Error;
 	}