Browse Source

Make all core vector relational constexpr

Christophe Riccio 7 years ago
parent
commit
65655abd32
3 changed files with 102 additions and 37 deletions
  1. 89 16
      glm/detail/func_vector_relational.inl
  2. 8 16
      glm/detail/type_int.hpp
  3. 5 5
      glm/vector_relational.hpp

+ 89 - 16
glm/detail/func_vector_relational.inl

@@ -14,10 +14,15 @@ namespace detail
 {
 	enum relational_type
 	{
+		EQUAL,
+		NOT_EQUAL,
 		LESS,
 		LESS_EQUAL,
 		GREATER,
-		GREATER_EQUAL
+		GREATER_EQUAL,
+		ANY,
+		ALL,
+		NOT
 	};
 
 	template <relational_type R>
@@ -27,6 +32,26 @@ namespace detail
 		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1);
 	};
 
+	template <>
+	struct relational<EQUAL>
+	{
+		template<typename T>
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1)
+		{
+			return Src0 == Src1;
+		}
+	};
+
+	template <>
+	struct relational<NOT_EQUAL>
+	{
+		template<typename T>
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1)
+		{
+			return Src0 != Src1;
+		}
+	};
+
 	template <>
 	struct relational<LESS>
 	{
@@ -67,6 +92,59 @@ namespace detail
 		}
 	};
 
+	template <>
+	struct relational<ANY>
+	{
+		template<typename T>
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1)
+		{
+			return Src0 || Src1;
+		}
+	};
+
+	template <>
+	struct relational<ALL>
+	{
+		template<typename T>
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T Src1)
+		{
+			return Src0 && Src1;
+		}
+	};
+
+	template <>
+	struct relational<NOT>
+	{
+		template<typename T>
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static bool call(T Src0, T)
+		{
+			return !Src0;
+		}
+	};
+
+
+
+	template<length_t I, length_t N, relational_type R>
+	struct reduce_relational
+	{
+		template<typename vecType>
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static void call(bool& Dst, vecType const& Src)
+		{
+			Dst = relational<R>::call(Dst, Src[I]);
+			reduce_relational<I + 1, N, R>::call(Dst, Src);
+		}
+	};
+
+	template <length_t N, relational_type R>
+	struct reduce_relational<N, N, R>
+	{
+		template<typename vecType>
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static void call(bool&, vecType const&)
+		{}
+	};
+
+
+
 	template<length_t I, length_t N, relational_type R>
 	struct loop_relational
 	{
@@ -120,47 +198,42 @@ namespace detail
 	}
 
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
 	{
 		vec<L, bool, Q> Result GLM_BUG_VC_INIT;
-		for(length_t i = 0; i < x.length(); ++i)
-			Result[i] = detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(x[i], y[i]);
+		detail::loop_relational<0, L, detail::EQUAL>::call(Result, x, y);
 		return Result;
 	}
 
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
 	{
 		vec<L, bool, Q> Result GLM_BUG_VC_INIT;
-		for(length_t i = 0; i < x.length(); ++i)
-			Result[i] = !detail::compute_equal<T, std::numeric_limits<T>::is_iec559>::call(x[i], y[i]);
+		detail::loop_relational<0, L, detail::NOT_EQUAL>::call(Result, x, y);
 		return Result;
 	}
 
 	template<length_t L, qualifier Q>
-	GLM_FUNC_QUALIFIER bool any(vec<L, bool, Q> const& v)
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool any(vec<L, bool, Q> const& v)
 	{
 		bool Result = false;
-		for(length_t i = 0; i < v.length(); ++i)
-			Result = Result || v[i];
+		detail::reduce_relational<0, L, detail::ANY>::call(Result, v);
 		return Result;
 	}
 
 	template<length_t L, qualifier Q>
-	GLM_FUNC_QUALIFIER bool all(vec<L, bool, Q> const& v)
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR bool all(vec<L, bool, Q> const& v)
 	{
 		bool Result = true;
-		for(length_t i = 0; i < v.length(); ++i)
-			Result = Result && v[i];
+		detail::reduce_relational<0, L, detail::ALL>::call(Result, v);
 		return Result;
 	}
 
 	template<length_t L, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<L, bool, Q> not_(vec<L, bool, Q> const& v)
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR vec<L, bool, Q> not_(vec<L, bool, Q> const& v)
 	{
 		vec<L, bool, Q> Result;
-		for(length_t i = 0; i < v.length(); ++i)
-			Result[i] = !v[i];
+		detail::loop_relational<0, L, detail::NOT>::call(Result, v, v);
 		return Result;
 	}
 }//namespace glm

+ 8 - 16
glm/detail/type_int.hpp

@@ -258,28 +258,20 @@ namespace detail
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.7.2 Precision Qualifier</a>
 	typedef detail::highp_uint_t			highp_uint;
 
-#if(!defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
-	typedef mediump_int					int_t;
-#elif(defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
-	typedef highp_int					int_t;
-#elif(!defined(GLM_PRECISION_HIGHP_INT) && defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
-	typedef mediump_int					int_t;
-#elif(!defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && defined(GLM_PRECISION_LOWP_INT))
+#if GLM_CONFIG_PRECISION_INT == GLM_LOWP
 	typedef lowp_int					int_t;
+#elif GLM_CONFIG_PRECISION_INT == GLM_MEDIUMP
+	typedef mediump_int					int_t;
 #else
-#	error "GLM error: multiple default precision requested for signed integer types"
+	typedef highp_int					int_t;
 #endif
 
-#if(!defined(GLM_PRECISION_HIGHP_UINT) && !defined(GLM_PRECISION_MEDIUMP_UINT) && !defined(GLM_PRECISION_LOWP_UINT))
-	typedef mediump_uint				uint_t;
-#elif(defined(GLM_PRECISION_HIGHP_UINT) && !defined(GLM_PRECISION_MEDIUMP_UINT) && !defined(GLM_PRECISION_LOWP_UINT))
-	typedef highp_uint					uint_t;
-#elif(!defined(GLM_PRECISION_HIGHP_UINT) && defined(GLM_PRECISION_MEDIUMP_UINT) && !defined(GLM_PRECISION_LOWP_UINT))
-	typedef mediump_uint				uint_t;
-#elif(!defined(GLM_PRECISION_HIGHP_UINT) && !defined(GLM_PRECISION_MEDIUMP_UINT) && defined(GLM_PRECISION_LOWP_UINT))
+#if GLM_CONFIG_PRECISION_UINT == GLM_LOWP
 	typedef lowp_uint					uint_t;
+#elif GLM_CONFIG_PRECISION_UINT == GLM_MEDIUMP
+	typedef mediump_uint				uint_t;
 #else
-#	error "GLM error: multiple default precision requested for unsigned integer types"
+	typedef highp_uint					uint_t;
 #endif
 
 	/// Unsigned integer type.

+ 5 - 5
glm/vector_relational.hpp

@@ -73,7 +73,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/equal.xml">GLSL equal man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7 Vector Relational Functions</a>
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_DECL vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
+	GLM_FUNC_DECL GLM_CONSTEXPR vec<L, bool, Q> equal(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
 
 	/// Returns the component-wise comparison of result x != y.
 	///
@@ -83,7 +83,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/notEqual.xml">GLSL notEqual man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7 Vector Relational Functions</a>
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_DECL vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
+	GLM_FUNC_DECL GLM_CONSTEXPR vec<L, bool, Q> notEqual(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
 
 	/// Returns true if any component of x is true.
 	///
@@ -92,7 +92,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/any.xml">GLSL any man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7 Vector Relational Functions</a>
 	template<length_t L, qualifier Q>
-	GLM_FUNC_DECL bool any(vec<L, bool, Q> const& v);
+	GLM_FUNC_DECL GLM_CONSTEXPR bool any(vec<L, bool, Q> const& v);
 
 	/// Returns true if all components of x are true.
 	///
@@ -101,7 +101,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/all.xml">GLSL all man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7 Vector Relational Functions</a>
 	template<length_t L, qualifier Q>
-	GLM_FUNC_DECL bool all(vec<L, bool, Q> const& v);
+	GLM_FUNC_DECL GLM_CONSTEXPR bool all(vec<L, bool, Q> const& v);
 
 	/// Returns the component-wise logical complement of x.
 	/// /!\ Because of language incompatibilities between C++ and GLSL, GLM defines the function not but not_ instead.
@@ -111,7 +111,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/not.xml">GLSL not man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.7 Vector Relational Functions</a>
 	template<length_t L, qualifier Q>
-	GLM_FUNC_DECL vec<L, bool, Q> not_(vec<L, bool, Q> const& v);
+	GLM_FUNC_DECL GLM_CONSTEXPR vec<L, bool, Q> not_(vec<L, bool, Q> const& v);
 
 	/// @}
 }//namespace glm