Browse Source

Replace function instanciations with macros by templates

Christophe Riccio 11 years ago
parent
commit
bf08a0e234

+ 1 - 1
glm/detail/func_common.inl

@@ -211,7 +211,7 @@ namespace detail
 	template <typename T, precision P, template <typename, precision> class vecType>
 	GLM_FUNC_QUALIFIER vecType<T, P> round(vecType<T, P> const & x)
 	{
-		return detail::functor1<T, P, vecType>::call(::std::round, x);
+		return detail::functor1<T, P, vecType>::call(round, x);
 	}
 
 /*

+ 13 - 14
glm/detail/func_exponential.hpp

@@ -54,8 +54,8 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/pow.xml">GLSL pow man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType pow(genType const & base, genType const & exponent);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> pow(vecType<T, P> const & base, vecType<T, P> const & exponent);
 
 	/// Returns the natural exponentiation of x, i.e., e^x.
 	///
@@ -64,8 +64,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp.xml">GLSL exp man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType exp(genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> exp(vecType<T, P> const & v);
 
 	/// Returns the natural logarithm of x, i.e., 
 	/// returns the value y which satisfies the equation x = e^y. 
@@ -76,8 +76,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log.xml">GLSL log man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType log(genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> log(vecType<T, P> const & v);
 
 	/// Returns 2 raised to the x power.
 	/// 
@@ -86,8 +86,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/exp2.xml">GLSL exp2 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType exp2(genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> exp2(vecType<T, P> const & v);
 
 	/// Returns the base 2 log of x, i.e., returns the value y, 
 	/// which satisfies the equation x = 2 ^ y.
@@ -97,8 +97,8 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/log2.xml">GLSL log2 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
-	template <typename genType>
-	GLM_FUNC_DECL genType log2(genType x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> log2(vecType<T, P> const & v);
 
 	/// Returns the positive square root of x.
 	/// 
@@ -109,9 +109,8 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
 	//template <typename genType>
 	//GLM_FUNC_DECL genType sqrt(genType const & x);
-
 	template <typename T, precision P, template <typename, precision> class vecType>
-	GLM_FUNC_DECL vecType<T, P> sqrt(vecType<T, P> const & x);
+	GLM_FUNC_DECL vecType<T, P> sqrt(vecType<T, P> const & v);
 	
 	/// Returns the reciprocal of the positive square root of x.
 	/// 
@@ -120,8 +119,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inversesqrt.xml">GLSL inversesqrt man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.2 Exponential Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType inversesqrt(genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> inversesqrt(vecType<T, P> const & v);
 
 	/// @}
 }//namespace glm

+ 36 - 73
glm/detail/func_exponential.inl

@@ -36,19 +36,15 @@ namespace glm{
 namespace detail
 {
 	template <bool isFloat>
-	struct compute_log2
-	{
-		template <typename T>
-		T operator() (T const & Value) const;
-	};
+	struct compute_log2{};
 
 	template <>
 	struct compute_log2<true>
 	{
 		template <typename T>
-		GLM_FUNC_QUALIFIER T operator() (T const & Value) const
+		GLM_FUNC_QUALIFIER T operator() (T Value) const
 		{
-#			if(GLM_LANG & GLM_LANG_CXX11_FLAG)
+#			if GLM_LANG & GLM_LANG_CXX11_FLAG
 				return std::log2(Value);
 #			else
 				return std::log(Value) * static_cast<T>(1.4426950408889634073599246810019);
@@ -84,28 +80,42 @@ namespace detail
 
 	// pow
 	using std::pow;
-	VECTORIZE_VEC_VEC(pow)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> pow(vecType<T, P> const & base, vecType<T, P> const & exponent)
+	{
+		return detail::functor2<T, P, vecType>::call(::std::pow, base, exponent);
+	}
 
 	// exp
 	using std::exp;
-	VECTORIZE_VEC(exp)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> exp(vecType<T, P> const & x)
+	{
+		return detail::functor1<T, P, vecType>::call(::std::exp, x);
+	}
 
 	// log
 	using std::log;
-	VECTORIZE_VEC(log)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> log(vecType<T, P> const & x)
+	{
+		return detail::functor1<T, P, vecType>::call(::std::log, x);
+	}
 
 	//exp2, ln2 = 0.69314718055994530941723212145818f
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType exp2(genType const & x)
+	GLM_FUNC_QUALIFIER genType exp2(genType x)
 	{
-		GLM_STATIC_ASSERT(
-			std::numeric_limits<genType>::is_iec559,
-			"'exp2' only accept floating-point inputs");
+		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'exp2' only accept floating-point inputs");
 
 		return std::exp(static_cast<genType>(0.69314718055994530941723212145818) * x);
 	}
 
-	VECTORIZE_VEC(exp2)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> exp2(vecType<T, P> const & x)
+	{
+		return detail::functor1<T, P, vecType>::call(exp2, x);
+	}
 
 	// log2, ln2 = 0.69314718055994530941723212145818f
 	template <typename genType>
@@ -118,79 +128,32 @@ namespace detail
 		return detail::compute_log2<std::numeric_limits<genType>::is_iec559>()(x);
 	}
 
-	VECTORIZE_VEC(log2)
-
-	namespace detail
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> log2(vecType<T, P> const & x)
 	{
-		template <template <class, precision> class vecType, typename T, precision P>
-		struct compute_sqrt{};
-		
-		template <typename T, precision P>
-		struct compute_sqrt<tvec1, T, P>
-		{
-			GLM_FUNC_QUALIFIER static tvec1<T, P> call(tvec1<T, P> const & x)
-			{
-				return tvec1<T, P>(std::sqrt(x.x));
-			}
-		};
-		
-		template <typename T, precision P>
-		struct compute_sqrt<tvec2, T, P>
-		{
-			GLM_FUNC_QUALIFIER static tvec2<T, P> call(tvec2<T, P> const & x)
-			{
-				return tvec2<T, P>(std::sqrt(x.x), std::sqrt(x.y));
-			}
-		};
-		
-		template <typename T, precision P>
-		struct compute_sqrt<tvec3, T, P>
-		{
-			GLM_FUNC_QUALIFIER static tvec3<T, P> call(tvec3<T, P> const & x)
-			{
-				return tvec3<T, P>(std::sqrt(x.x), std::sqrt(x.y), std::sqrt(x.z));
-			}
-		};
-		
-		template <typename T, precision P>
-		struct compute_sqrt<tvec4, T, P>
-		{
-			GLM_FUNC_QUALIFIER static tvec4<T, P> call(tvec4<T, P> const & x)
-			{
-				return tvec4<T, P>(std::sqrt(x.x), std::sqrt(x.y), std::sqrt(x.z), std::sqrt(x.w));
-			}
-		};
-	}//namespace detail
-	
+		return detail::functor1<T, P, vecType>::call(log2, x);
+	}
+
 	// sqrt
 	using std::sqrt;
 	template <typename T, precision P, template <typename, precision> class vecType>
 	GLM_FUNC_QUALIFIER vecType<T, P> sqrt(vecType<T, P> const & x)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'sqrt' only accept floating-point inputs");
-		return detail::compute_sqrt<vecType, T, P>::call(x);
+		return detail::functor1<T, P, vecType>::call(sqrt, x);
 	}
 
 	// inversesqrt
-	GLM_FUNC_QUALIFIER float inversesqrt(float const & x)
-	{
-		return 1.0f / sqrt(x);
-	}
-	
-	GLM_FUNC_QUALIFIER double inversesqrt(double const & x)
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType inversesqrt(genType x)
 	{
-		return 1.0 / sqrt(x);
+		return static_cast<genType>(1) / sqrt(x);
 	}
 	
-	template <template <class, precision> class vecType, typename T, precision P>
-	GLM_FUNC_QUALIFIER vecType<T, P> inversesqrt
-	(
-		vecType<T, P> const & x
-	)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> inversesqrt(vecType<T, P> const & x)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'inversesqrt' only accept floating-point inputs");
 		return detail::compute_inversesqrt<vecType, T, P>::call(x);
 	}
-
-	VECTORIZE_VEC(inversesqrt)
 }//namespace glm

+ 11 - 21
glm/detail/func_geometric.hpp

@@ -48,9 +48,9 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/length.xml">GLSL length man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL typename genType::value_type length(
-		genType const & x); 
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL T length(
+		vecType<T, P> const & x);
 
 	/// Returns the distance betwwen p0 and p1, i.e., length(p0 - p1).
 	///
@@ -58,10 +58,10 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/distance.xml">GLSL distance man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL typename genType::value_type distance(
-		genType const & p0, 
-		genType const & p1);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL T distance(
+		vecType<T, P> const & p0,
+		vecType<T, P> const & p1);
 
 	/// Returns the dot product of x and y, i.e., result = x * y.
 	///
@@ -74,17 +74,6 @@ namespace glm
 		vecType<T, P> const & x,
 		vecType<T, P> const & y);
 
-	/// Returns the dot product of x and y, i.e., result = x * y.
-	///
-	/// @tparam genType Floating-point vector types.
-	/// 
-	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/dot.xml">GLSL dot man page</a>
-	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename genType>
-	GLM_FUNC_DECL genType dot(
-		genType const & x,
-		genType const & y);
-
 	/// Returns the cross product of x and y.
 	///
 	/// @tparam valType Floating-point scalar types.
@@ -97,12 +86,13 @@ namespace glm
 		tvec3<T, P> const & y);
 
 	/// Returns a vector in the same direction as x but with length of 1.
+	/// According to issue 10 GLSL 1.10 specification, if length(x) == 0 then result is undefined and generate an error.
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/normalize.xml">GLSL normalize man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename genType>
-	GLM_FUNC_DECL genType normalize(
-		genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> normalize(
+		vecType<T, P> const & x);
 
 	/// If dot(Nref, I) < 0.0, return N, otherwise, return -N.
 	///

+ 27 - 169
glm/detail/func_geometric.inl

@@ -41,14 +41,9 @@ namespace detail
 	template <typename T, precision P>
 	struct compute_dot<tvec1, T, P>
 	{
-		GLM_FUNC_QUALIFIER static T call(tvec1<T, P> const & x, tvec1<T, P> const & y)
+		GLM_FUNC_QUALIFIER static T call(tvec1<T, P> const & a, tvec1<T, P> const & b)
 		{
-#			ifdef __CUDACC__ // Wordaround for a CUDA compiler bug up to CUDA6
-				tvec1<T, P> tmp(x * y);
-				return tmp.x;
-#			else
-				return tvec1<T, P>(x * y).x;
-#			endif
+			return a.x * b.x;
 		}
 	};
 
@@ -85,139 +80,54 @@ namespace detail
 
 	// length
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType length
-	(
-		genType const & x
-	)
+	GLM_FUNC_QUALIFIER genType length(genType x)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'length' only accept floating-point inputs");
 
 		return abs(x);
 	}
 
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER T length(tvec2<T, P> const & v)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'length' only accept floating-point inputs");
-
-		T sqr = v.x * v.x + v.y * v.y;
-		return sqrt(sqr);
-	}
-
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER T length(tvec3<T, P> const & v)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'length' only accept floating-point inputs");
-
-		T sqr = v.x * v.x + v.y * v.y + v.z * v.z;
-		return sqrt(sqr);
-	}
-
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER T length(tvec4<T, P> const & v)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER T length(vecType<T, P> const & v)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'length' only accept floating-point inputs");
 
-		T sqr = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
-		return sqrt(sqr);
+		return sqrt(dot(v, v));
 	}
 
 	// distance
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType distance
-	(
-		genType const & p0,
-		genType const & p1
-	)
+	GLM_FUNC_QUALIFIER genType distance(genType const & p0, genType const & p1)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'distance' only accept floating-point inputs");
 
 		return length(p1 - p0);
 	}
 
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER T distance
-	(
-		tvec2<T, P> const & p0,
-		tvec2<T, P> const & p1
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'distance' only accept floating-point inputs");
-
-		return length(p1 - p0);
-	}
-
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER T distance
-	(
-		tvec3<T, P> const & p0,
-		tvec3<T, P> const & p1
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'distance' only accept floating-point inputs");
-
-		return length(p1 - p0);
-	}
-
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER T distance
-	(
-		tvec4<T, P> const & p0,
-		tvec4<T, P> const & p1
-	)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> distance(vecType<T, P> const & p0, vecType<T, P> const & p1)
 	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'distance' only accept floating-point inputs");
-
 		return length(p1 - p0);
 	}
 
 	// dot
 	template <typename T>
-	GLM_FUNC_QUALIFIER T dot
-	(
-		T const & x,
-		T const & y
-	)
+	GLM_FUNC_QUALIFIER T dot(T x, T y)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'dot' only accept floating-point inputs");
 		return x * y;
 	}
 
 	template <typename T, precision P, template <typename, precision> class vecType>
-	GLM_FUNC_QUALIFIER T dot
-	(
-		vecType<T, P> const & x,
-		vecType<T, P> const & y
-	)
+	GLM_FUNC_QUALIFIER T dot(vecType<T, P> const & x, vecType<T, P> const & y)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'dot' only accept floating-point inputs");
 		return detail::compute_dot<vecType, T, P>::call(x, y);
 	}
 
-/* // SSE3
-	GLM_FUNC_QUALIFIER float dot(const tvec4<float>& x, const tvec4<float>& y)
-	{
-		float Result;
-		__asm
-		{
-			mov		esi, x
-			mov		edi, y
-			movaps	xmm0, [esi]
-			mulps	xmm0, [edi]
-			haddps(	_xmm0, _xmm0 )
-			haddps(	_xmm0, _xmm0 )
-			movss	Result, xmm0
-		}
-		return Result;
-	}
-*/
 	// cross
 	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER tvec3<T, P> cross
-	(
-		tvec3<T, P> const & x,
-		tvec3<T, P> const & y
-	)
+	GLM_FUNC_QUALIFIER tvec3<T, P> cross(tvec3<T, P> const & x, tvec3<T, P> const & y)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'cross' only accept floating-point inputs");
 
@@ -229,111 +139,59 @@ namespace detail
 
 	// normalize
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType normalize
-	(
-		genType const & x
-	)
+	GLM_FUNC_QUALIFIER genType normalize(genType const & x)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'normalize' only accept floating-point inputs");
 
 		return x < genType(0) ? genType(-1) : genType(1);
 	}
 
-	// According to issue 10 GLSL 1.10 specification, if length(x) == 0 then result is undefine and generate an error
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER tvec2<T, P> normalize
-	(
-		tvec2<T, P> const & x
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'normalize' only accept floating-point inputs");
-		
-		T sqr = x.x * x.x + x.y * x.y;
-		return x * inversesqrt(sqr);
-	}
-
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER tvec3<T, P> normalize
-	(
-		tvec3<T, P> const & x
-	)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> normalize(vecType<T, P> const & x)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'normalize' only accept floating-point inputs");
 
-		T sqr = x.x * x.x + x.y * x.y + x.z * x.z;
-		return x * inversesqrt(sqr);
-	}
-
-	template <typename T, precision P>
-	GLM_FUNC_QUALIFIER tvec4<T, P> normalize
-	(
-		tvec4<T, P> const & x
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'normalize' only accept floating-point inputs");
-		
-		T sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
-		return x * inversesqrt(sqr);
+		return x * inversesqrt(dot(x, x));
 	}
 
 	// faceforward
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType faceforward
-	(
-		genType const & N,
-		genType const & I,
-		genType const & Nref
-	)
+	GLM_FUNC_QUALIFIER genType faceforward(genType const & N, genType const & I, genType const & Nref)
 	{
-		return dot(Nref, I) < 0 ? N : -N;
+		return dot(Nref, I) < static_cast<genType>(0) ? N : -N;
 	}
 
 	// reflect
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType reflect
-	(
-		genType const & I,
-		genType const & N
-	)
+	GLM_FUNC_QUALIFIER genType reflect(genType const & I, genType const & N)
 	{
-		return I - N * dot(N, I) * genType(2);
+		return I - N * dot(N, I) * static_cast<genType>(2);
 	}
 
 	// refract
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType refract
-	(
-		genType const & I,
-		genType const & N,
-		genType const & eta
-	)
+	GLM_FUNC_QUALIFIER genType refract(genType const & I, genType const & N, genType const & eta)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'refract' only accept floating-point inputs");
 
 		genType dotValue = dot(N, I);
-		genType k = genType(1) - eta * eta * (genType(1) - dotValue * dotValue);
-		if(k < genType(0))
-			return genType(0);
+		genType k = static_cast<genType>(1) - eta * eta * (static_cast<genType>(1) - dotValue * dotValue);
+		if(k < static_cast<genType>(0))
+			return static_cast<genType>(0);
 		else
 			return eta * I - (eta * dotValue + sqrt(k)) * N;
 	}
 
 	template <typename T, precision P, template <typename, precision> class vecType>
-	GLM_FUNC_QUALIFIER vecType<T, P> refract
-	(
-		vecType<T, P> const & I,
-		vecType<T, P> const & N,
-		T const & eta
-	)
+	GLM_FUNC_QUALIFIER vecType<T, P> refract(vecType<T, P> const & I, vecType<T, P> const & N, T const & eta)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'refract' only accept floating-point inputs");
 
 		T dotValue = dot(N, I);
-		T k = T(1) - eta * eta * (T(1) - dotValue * dotValue);
-		if(k < T(0))
+		T k = static_cast<T>(1) - eta * eta * (static_cast<T>(1) - dotValue * dotValue);
+		if(k < static_cast<T>(0))
 			return vecType<T, P>(0);
 		else
 			return eta * I - (eta * dotValue + std::sqrt(k)) * N;
 	}
-
 }//namespace glm

+ 31 - 30
glm/detail/func_trigonometric.hpp

@@ -40,6 +40,7 @@
 #pragma once
 
 #include "setup.hpp"
+#include "precision.hpp"
 
 namespace glm
 {
@@ -52,8 +53,8 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/radians.xml">GLSL radians man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType>
-	GLM_FUNC_DECL genType radians(genType const & degrees);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> radians(vecType<T, P> const & degrees);
 
 	/// Converts radians to degrees and returns the result.
 	///
@@ -61,8 +62,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/degrees.xml">GLSL degrees man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType>
-	GLM_FUNC_DECL genType degrees(genType const & radians);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> degrees(vecType<T, P> const & radians);
 
 	/// The standard trigonometric sine function. 
 	/// The values returned by this function will range from [-1, 1].
@@ -71,8 +72,8 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sin.xml">GLSL sin man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType sin(genType const & angle);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> sin(vecType<T, P> const & angle);
 
 	/// The standard trigonometric cosine function. 
 	/// The values returned by this function will range from [-1, 1].
@@ -81,8 +82,8 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cos.xml">GLSL cos man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType cos(genType const & angle);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> cos(vecType<T, P> const & angle);
 
 	/// The standard trigonometric tangent function.
 	///
@@ -90,8 +91,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/tan.xml">GLSL tan man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType tan(genType const & angle); 
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> tan(vecType<T, P> const & angle); 
 
 	/// Arc sine. Returns an angle whose sine is x. 
 	/// The range of values returned by this function is [-PI/2, PI/2]. 
@@ -101,8 +102,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/asin.xml">GLSL asin man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType asin(genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> asin(vecType<T, P> const & x);
 
 	/// Arc cosine. Returns an angle whose sine is x. 
 	/// The range of values returned by this function is [0, PI]. 
@@ -112,8 +113,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/acos.xml">GLSL acos man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType acos(genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> acos(vecType<T, P> const & x);
 
 	/// Arc tangent. Returns an angle whose tangent is y/x. 
 	/// The signs of x and y are used to determine what 
@@ -125,8 +126,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atan.xml">GLSL atan man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType atan(genType const & y, genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> atan(vecType<T, P> const & y, vecType<T, P> const & x);
 
 	/// Arc tangent. Returns an angle whose tangent is y_over_x. 
 	/// The range of values returned by this function is [-PI/2, PI/2].
@@ -135,8 +136,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atan.xml">GLSL atan man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType atan(genType const & y_over_x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> atan(vecType<T, P> const & y_over_x);
 
 	/// Returns the hyperbolic sine function, (exp(x) - exp(-x)) / 2
 	///
@@ -144,8 +145,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/sinh.xml">GLSL sinh man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType sinh(genType const & angle);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> sinh(vecType<T, P> const & angle);
 
 	/// Returns the hyperbolic cosine function, (exp(x) + exp(-x)) / 2
 	///
@@ -153,8 +154,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cosh.xml">GLSL cosh man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType cosh(genType const & angle);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> cosh(vecType<T, P> const & angle);
 
 	/// Returns the hyperbolic tangent function, sinh(angle) / cosh(angle)
 	///
@@ -162,8 +163,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/tanh.xml">GLSL tanh man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType tanh(genType const & angle);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> tanh(vecType<T, P> const & angle);
 
 	/// Arc hyperbolic sine; returns the inverse of sinh.
 	///
@@ -171,8 +172,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/asinh.xml">GLSL asinh man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType asinh(genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> asinh(vecType<T, P> const & x);
 	
 	/// Arc hyperbolic cosine; returns the non-negative inverse
 	/// of cosh. Results are undefined if x < 1.
@@ -181,8 +182,8 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/acosh.xml">GLSL acosh man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType acosh(genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> acosh(vecType<T, P> const & x);
 
 	/// Arc hyperbolic tangent; returns the inverse of tanh.
 	/// Results are undefined if abs(x) >= 1.
@@ -191,8 +192,8 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/atanh.xml">GLSL atanh man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.1 Angle and Trigonometry Functions</a>
-	template <typename genType> 
-	GLM_FUNC_DECL genType atanh(genType const & x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_DECL vecType<T, P> atanh(vecType<T, P> const & x);
 
 	/// @}
 }//namespace glm

+ 75 - 124
glm/detail/func_trigonometric.inl

@@ -34,191 +34,131 @@ namespace glm
 {
 	// radians
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType radians
-	(
-		genType const & degrees
-	)
+	GLM_FUNC_QUALIFIER genType radians(genType degrees)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'radians' only accept floating-point input");
 
-		return degrees * genType(0.01745329251994329576923690768489);
+		return degrees * static_cast<genType>(0.01745329251994329576923690768489);
 	}
 
-	VECTORIZE_VEC(radians)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> radians(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(radians, v);
+	}
 	
 	// degrees
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType degrees
-	(
-		genType const & radians
-	)
+	GLM_FUNC_QUALIFIER genType degrees(genType radians)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'degrees' only accept floating-point input");
 
-		return radians * genType(57.295779513082320876798154814105);
+		return radians * static_cast<genType>(57.295779513082320876798154814105);
 	}
 
-	VECTORIZE_VEC(degrees)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> degrees(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(degrees, v);
+	}
 
 	// sin
-	using std::sin;
-/*
-	template <typename genType>
-	GLM_FUNC_QUALIFIER genType sin
-	(
-		genType const & angle
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'sin' only accept floating-point input");
+	using ::std::sin;
 
-		return genType(::std::sin(angle));
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> sin(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(sin, v);
 	}
-*/
-	VECTORIZE_VEC(sin)
 
 	// cos
 	using std::cos;
-/*
-	template <typename genType>
-	GLM_FUNC_QUALIFIER genType cos(genType const & angle)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'cos' only accept floating-point input");
 
-		return genType(::std::cos(angle));
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> cos(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(cos, v);
 	}
-*/
-
-	VECTORIZE_VEC(cos)
 
 	// tan
 	using std::tan;
-/*
-	template <typename genType>
-	GLM_FUNC_QUALIFIER genType tan
-	(
-		genType const & angle
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'tan' only accept floating-point input");
 
-		return genType(::std::tan(angle));
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> tan(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(tan, v);
 	}
-*/
-
-	VECTORIZE_VEC(tan)
 
 	// asin
 	using std::asin;
-/*
-	template <typename genType>
-	GLM_FUNC_QUALIFIER genType asin
-	(
-		genType const & x
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'asin' only accept floating-point input");
 
-		return genType(::std::asin(x));
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> asin(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(asin, v);
 	}
-*/
-	VECTORIZE_VEC(asin)
 
 	// acos
 	using std::acos;
-/*
-	template <typename genType>
-	GLM_FUNC_QUALIFIER genType acos
-	(
-		genType const & x
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'acos' only accept floating-point input");
 
-		return ::std::acos(x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> acos(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(acos, v);
 	}
-*/
-	VECTORIZE_VEC(acos)
 
 	// atan
 	template <typename genType>
-	GLM_FUNC_QUALIFIER genType atan
-	(
-		genType const & y,
-		genType const & x
-	)
+	GLM_FUNC_QUALIFIER genType atan(genType const & y, genType const & x)
 	{
 		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'atan' only accept floating-point input");
 
 		return ::std::atan2(y, x);
 	}
 
-	VECTORIZE_VEC_VEC(atan)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> atan(vecType<T, P> const & a, vecType<T, P> const & b)
+	{
+		return detail::functor2<T, P, vecType>::call(atan2, a, b);
+	}
 
 	using std::atan;
-/*
-	template <typename genType>
-	GLM_FUNC_QUALIFIER genType atan
-	(
-		genType const & x
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'atan' only accept floating-point input");
 
-		return ::std::atan(x);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> atan(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(atan, v);
 	}
-*/
-	VECTORIZE_VEC(atan)
 
 	// sinh
 	using std::sinh;
-/*
-	template <typename genType> 
-	GLM_FUNC_QUALIFIER genType sinh
-	(
-		genType const & angle
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'sinh' only accept floating-point input");
 
-		return ::std::sinh(angle);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> sinh(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(sinh, v);
 	}
-*/
-	VECTORIZE_VEC(sinh)
 
 	// cosh
 	using std::cosh;
-/*
-	template <typename genType> 
-	GLM_FUNC_QUALIFIER genType cosh
-	(
-		genType const & angle
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'cosh' only accept floating-point input");
 
-		return ::std::cosh(angle);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> cosh(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(cosh, v);
 	}
-*/
-	VECTORIZE_VEC(cosh)
 
 	// tanh
 	using std::tanh;
-/*
-	template <typename genType>
-	GLM_FUNC_QUALIFIER genType tanh
-	(
-		genType const & angle
-	)
-	{
-		GLM_STATIC_ASSERT(std::numeric_limits<genType>::is_iec559, "'tanh' only accept floating-point input");
 
-		return ::std::tanh(angle);
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> tanh(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(tanh, v);
 	}
-*/
-	VECTORIZE_VEC(tanh)
 
 	// asinh
-#	if(GLM_LANG & GLM_LANG_CXX11_FLAG)
+#	if GLM_LANG & GLM_LANG_CXX11_FLAG
 		using std::asinh;
 #	else
 		template <typename genType> 
@@ -230,10 +170,14 @@ namespace glm
 		}
 #	endif
 
-	VECTORIZE_VEC(asinh)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> asinh(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(asinh, v);
+	}
 
 	// acosh
-#	if(GLM_LANG & GLM_LANG_CXX11_FLAG)
+#	if GLM_LANG & GLM_LANG_CXX11_FLAG
 		using std::acosh;
 #	else
 		template <typename genType> 
@@ -247,10 +191,14 @@ namespace glm
 		}
 #	endif
 
-	VECTORIZE_VEC(acosh)
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> acosh(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(acosh, v);
+	}
 
 	// atanh
-#	if(GLM_LANG & GLM_LANG_CXX11_FLAG)
+#	if GLM_LANG & GLM_LANG_CXX11_FLAG
 		using std::atanh;
 #	else
 		template <typename genType>
@@ -264,6 +212,9 @@ namespace glm
 		}
 #	endif
 
-	VECTORIZE_VEC(atanh)
-
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<T, P> atanh(vecType<T, P> const & v)
+	{
+		return detail::functor1<T, P, vecType>::call(atanh, v);
+	}
 }//namespace glm

+ 2 - 1
test/core/core_func_exponential.cpp

@@ -99,7 +99,8 @@ int test_inversesqrt()
 
 	for(float f = 0.001f; f < 10.f; f *= 1.001f)
 	{
-		glm::lowp_fvec1 lowp_v = glm::inversesqrt(glm::lowp_fvec1(f));
+		glm::lowp_fvec1 u(f);
+		glm::lowp_fvec1 lowp_v = glm::inversesqrt(u);
 		float defaultp_v = glm::inversesqrt(f);
 
 		ulp = glm::max(glm::float_distance(lowp_v.x, defaultp_v), ulp);