Kaynağa Gözat

Make min, max, mix and clamp constexpr

These functions were already marked constexpr in the header, but their
implementations relied on non-constexpr functions. Mark those as
constexpr.
0xf00ff00f 1 ay önce
ebeveyn
işleme
b1fed40786
2 değiştirilmiş dosya ile 61 ekleme ve 11 silme
  1. 11 11
      glm/detail/func_common.inl
  2. 50 0
      test/core/core_func_common.cpp

+ 11 - 11
glm/detail/func_common.inl

@@ -47,12 +47,12 @@ namespace detail
 {
 	template<typename T>
 	struct TMin {
-		GLM_FUNC_QUALIFIER T operator()(const T& a, const T& b) { return min(a, b); }
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR T operator()(const T& a, const T& b) { return min(a, b); }
 	};
 
 	template<typename T>
 	struct TMax {
-		GLM_FUNC_QUALIFIER T operator()(const T& a, const T& b) { return max(a, b); }
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR T operator()(const T& a, const T& b) { return max(a, b); }
 	};
 
 	template<typename T>
@@ -87,7 +87,7 @@ namespace detail
 	template<length_t L, typename T, typename U, qualifier Q, bool Aligned>
 	struct compute_mix_vector
 	{
-		GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, U, Q> const& a)
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, U, Q> const& a)
 		{
 			static_assert(std::numeric_limits<U>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a");
 
@@ -98,7 +98,7 @@ namespace detail
 	template<length_t L, typename T, qualifier Q, bool Aligned>
 	struct compute_mix_vector<L, T, bool, Q, Aligned>
 	{
-		GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, bool, Q> const& a)
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, vec<L, bool, Q> const& a)
 		{
 			vec<L, T, Q> Result(0);
 			for(length_t i = 0; i < x.length(); ++i)
@@ -110,7 +110,7 @@ namespace detail
 	template<length_t L, typename T, typename U, qualifier Q, bool Aligned>
 	struct compute_mix_scalar
 	{
-		GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, U const& a)
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, U const& a)
 		{
 			static_assert(std::numeric_limits<U>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a");
 
@@ -121,7 +121,7 @@ namespace detail
 	template<length_t L, typename T, qualifier Q, bool Aligned>
 	struct compute_mix_scalar<L, T, bool, Q, Aligned>
 	{
-		GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, bool const& a)
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y, bool const& a)
 		{
 			return a ? y : x;
 		}
@@ -130,7 +130,7 @@ namespace detail
 	template<typename T, typename U>
 	struct compute_mix
 	{
-		GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, U const& a)
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(T const& x, T const& y, U const& a)
 		{
 			static_assert(std::numeric_limits<U>::is_iec559 || GLM_CONFIG_UNRESTRICTED_FLOAT || GLM_CONFIG_UNRESTRICTED_GENTYPE, "'mix' only accept floating-point inputs for the interpolator a");
 
@@ -141,7 +141,7 @@ namespace detail
 	template<typename T>
 	struct compute_mix<T, bool>
 	{
-		GLM_FUNC_QUALIFIER static T call(T const& x, T const& y, bool const& a)
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static T call(T const& x, T const& y, bool const& a)
 		{
 			return a ? y : x;
 		}
@@ -237,7 +237,7 @@ namespace detail
 	template<length_t L, typename T, qualifier Q, bool Aligned>
 	struct compute_min_vector
 	{
-		GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
 		{
 			return detail::functor2<vec, L, T, Q>::call(TMin<T>(), x, y);
 		}
@@ -246,7 +246,7 @@ namespace detail
 	template<length_t L, typename T, qualifier Q, bool Aligned>
 	struct compute_max_vector
 	{
-		GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& y)
 		{
 			return detail::functor2<vec, L, T, Q>::call(TMax<T>(), x, y);
 		}
@@ -255,7 +255,7 @@ namespace detail
 	template<length_t L, typename T, qualifier Q, bool Aligned>
 	struct compute_clamp_vector
 	{
-		GLM_FUNC_QUALIFIER static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal)
+		GLM_FUNC_QUALIFIER GLM_CONSTEXPR static vec<L, T, Q> call(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal)
 		{
 			return min(max(x, minVal), maxVal);
 		}

+ 50 - 0
test/core/core_func_common.cpp

@@ -298,6 +298,28 @@ namespace min_
 		return Error;
 	}
 
+#if GLM_HAS_CONSTEXPR
+	static int test_constexpr()
+	{
+		constexpr glm::vec1 A0 = glm::min(glm::vec1(1), glm::vec1(1));
+		static_assert(glm::all(glm::equal(A0, glm::vec1(1), glm::epsilon<float>())), "GLM: Failed constexpr");
+
+		constexpr glm::vec2 B0 = glm::min(glm::vec2(1), glm::vec2(1));
+		constexpr glm::vec2 B1 = glm::min(glm::vec2(1), 1.0f);
+		static_assert(glm::all(glm::equal(B0, B1, glm::epsilon<float>())), "GLM: Failed constexpr");
+
+		constexpr glm::vec3 C0 = glm::min(glm::vec3(1), glm::vec3(1));
+		constexpr glm::vec3 C1 = glm::min(glm::vec3(1), 1.0f);
+		static_assert(glm::all(glm::equal(C0, C1, glm::epsilon<float>())), "GLM: Failed constexpr");
+
+		constexpr glm::vec4 D0 = glm::min(glm::vec4(1), glm::vec4(1));
+		constexpr glm::vec4 D1 = glm::min(glm::vec4(1), 1.0f);
+		static_assert(glm::all(glm::equal(D0, D1, glm::epsilon<float>())), "GLM: Failed constexpr");
+
+		return 0;
+	}
+#endif
+
 	static int min_tern(int a, int b)
 	{
 		return a < b ? a : b;
@@ -383,6 +405,28 @@ namespace max_
 
 		return Error;
 	}
+
+#if GLM_HAS_CONSTEXPR
+	static int test_constexpr()
+	{
+		constexpr glm::vec1 A0 = glm::max(glm::vec1(1), glm::vec1(1));
+		static_assert(glm::all(glm::equal(A0, glm::vec1(1), glm::epsilon<float>())), "GLM: Failed constexpr");
+
+		constexpr glm::vec2 B0 = glm::max(glm::vec2(1), glm::vec2(1));
+		constexpr glm::vec2 B1 = glm::max(glm::vec2(1), 1.0f);
+		static_assert(glm::all(glm::equal(B0, B1, glm::epsilon<float>())), "GLM: Failed constexpr");
+
+		constexpr glm::vec3 C0 = glm::max(glm::vec3(1), glm::vec3(1));
+		constexpr glm::vec3 C1 = glm::max(glm::vec3(1), 1.0f);
+		static_assert(glm::all(glm::equal(C0, C1, glm::epsilon<float>())), "GLM: Failed constexpr");
+
+		constexpr glm::vec4 D0 = glm::max(glm::vec4(1), glm::vec4(1));
+		constexpr glm::vec4 D1 = glm::max(glm::vec4(1), 1.0f);
+		static_assert(glm::all(glm::equal(D0, D1, glm::epsilon<float>())), "GLM: Failed constexpr");
+
+		return 0;
+	}
+#endif
 }//namespace max_
 
 namespace clamp_
@@ -1386,7 +1430,13 @@ int main()
 	Error += step_::test();
 	Error += smoothstep_::test();
 	Error += max_::test();
+#if GLM_HAS_CONSTEXPR
+	Error += max_::test_constexpr();
+#endif
 	Error += min_::test();
+#if GLM_HAS_CONSTEXPR
+	Error += min_::test_constexpr();
+#endif
 	Error += clamp_::test();
 	Error += round_::test();
 	Error += roundEven::test();