Browse Source

Added missing fmin and fmax overloads

Christophe Riccio 7 years ago
parent
commit
61540a5204

+ 0 - 1
glm/ext/quaternion_relational.hpp

@@ -11,7 +11,6 @@
 #pragma once
 #pragma once
 
 
 // Dependency:
 // Dependency:
-#include "./quaternion_geometric.hpp"
 #include "../vector_relational.hpp"
 #include "../vector_relational.hpp"
 
 
 #if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
 #if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)

+ 2 - 2
glm/ext/quaternion_relational.inl

@@ -5,7 +5,7 @@ namespace glm
 	{
 	{
 		vec<4, bool, Q> Result;
 		vec<4, bool, Q> Result;
 		for(length_t i = 0; i < x.length(); ++i)
 		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]);
+			Result[i] = x[i] == y[i];
 		return Result;
 		return Result;
 	}
 	}
 
 
@@ -21,7 +21,7 @@ namespace glm
 	{
 	{
 		vec<4, bool, Q> Result;
 		vec<4, bool, Q> Result;
 		for(length_t i = 0; i < x.length(); ++i)
 		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]);
+			Result[i] = x[i] != y[i];
 		return Result;
 		return Result;
 	}
 	}
 
 

+ 32 - 7
glm/ext/vector_common.hpp

@@ -13,7 +13,8 @@
 #pragma once
 #pragma once
 
 
 // Dependency:
 // Dependency:
-#include "../glm.hpp"
+#include "../ext/scalar_common.hpp"
+#include "../common.hpp"
 
 
 #if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
 #if GLM_MESSAGES == GLM_ENABLE && !defined(GLM_EXT_INCLUDED)
 #	pragma message("GLM: GLM_EXT_vector_common extension included")
 #	pragma message("GLM: GLM_EXT_vector_common extension included")
@@ -86,6 +87,28 @@ namespace glm
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
 	GLM_FUNC_DECL vec<L, T, Q> fmin(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
 	GLM_FUNC_DECL vec<L, T, Q> fmin(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
 
 
+	/// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
+	///
+	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+	/// @tparam T Floating-point scalar types
+	/// @tparam Q Value from qualifier enum
+	///
+	/// @see ext_vector_common
+	/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmin">std::fmin documentation</a>
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_DECL vec<L, T, Q> fmin(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c);
+
+	/// Returns y if y < x; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
+	///
+	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
+	/// @tparam T Floating-point scalar types
+	/// @tparam Q Value from qualifier enum
+	///
+	/// @see ext_vector_common
+	/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmin">std::fmin documentation</a>
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_DECL vec<L, T, Q> fmin(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c, vec<L, T, Q> const& d);
+
 	/// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
 	/// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
 	///
 	///
 	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
 	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
@@ -95,7 +118,7 @@ namespace glm
 	/// @see ext_vector_common
 	/// @see ext_vector_common
 	/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
 	/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_DECL vec<L, T, Q> fmax(vec<L, T, Q> const& x, T y);
+	GLM_FUNC_DECL vec<L, T, Q> fmax(vec<L, T, Q> const& a, T b);
 
 
 	/// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
 	/// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
 	///
 	///
@@ -106,27 +129,29 @@ namespace glm
 	/// @see ext_vector_common
 	/// @see ext_vector_common
 	/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
 	/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_DECL vec<L, T, Q> fmax(vec<L, T, Q> const& x, vec<L, T, Q> const& y);
+	GLM_FUNC_DECL vec<L, T, Q> fmax(vec<L, T, Q> const& a, vec<L, T, Q> const& b);
 
 
-	/// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned.
+	/// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
 	///
 	///
 	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
 	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
 	/// @tparam T Floating-point scalar types
 	/// @tparam T Floating-point scalar types
 	/// @tparam Q Value from qualifier enum
 	/// @tparam Q Value from qualifier enum
 	///
 	///
 	/// @see ext_vector_common
 	/// @see ext_vector_common
+	/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_DECL vec<L, T, Q> fclamp(vec<L, T, Q> const& x, T minVal, T maxVal);
+	GLM_FUNC_DECL vec<L, T, Q> fmax(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c);
 
 
-	/// Returns min(max(x, minVal), maxVal) for each component in x. If one of the two arguments is NaN, the value of the other argument is returned.
+	/// Returns y if x < y; otherwise, it returns x. If one of the two arguments is NaN, the value of the other argument is returned.
 	///
 	///
 	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
 	/// @tparam L Integer between 1 and 4 included that qualify the dimension of the vector
 	/// @tparam T Floating-point scalar types
 	/// @tparam T Floating-point scalar types
 	/// @tparam Q Value from qualifier enum
 	/// @tparam Q Value from qualifier enum
 	///
 	///
 	/// @see ext_vector_common
 	/// @see ext_vector_common
+	/// @see <a href="http://en.cppreference.com/w/cpp/numeric/math/fmax">std::fmax documentation</a>
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_DECL vec<L, T, Q> fclamp(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal);
+	GLM_FUNC_DECL vec<L, T, Q> fmax(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c, vec<L, T, Q> const& d);
 
 
 	/// @}
 	/// @}
 }//namespace glm
 }//namespace glm

+ 22 - 6
glm/ext/vector_common.inl

@@ -1,3 +1,5 @@
+#include "../detail/_vectorize.hpp"
+
 namespace glm
 namespace glm
 {
 {
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
@@ -42,6 +44,20 @@ namespace glm
 		return detail::functor2<vec, L, T, Q>::call(fmin, a, b);
 		return detail::functor2<vec, L, T, Q>::call(fmin, a, b);
 	}
 	}
 
 
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<L, T, Q> fmin(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point inputs");
+		return fmin(fmin(a, b), c);
+	}
+
+	template<length_t L, typename T, qualifier Q>
+	GLM_FUNC_QUALIFIER vec<L, T, Q> fmin(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c, vec<L, T, Q> const& d)
+	{
+		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmin' only accept floating-point inputs");
+		return fmin(fmin(a, b), fmin(c, d));
+	}
+
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
 	GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, T b)
 	GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, T b)
 	{
 	{
@@ -57,16 +73,16 @@ namespace glm
 	}
 	}
 
 
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<L, T, Q> fclamp(vec<L, T, Q> const& x, T minVal, T maxVal)
+	GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c)
 	{
 	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fclamp' only accept floating-point inputs");
-		return fmin(fmax(x, vec<L, T, Q>(minVal)), vec<L, T, Q>(maxVal));
+		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point inputs");
+		return fmax(fmax(a, b), c);
 	}
 	}
 
 
 	template<length_t L, typename T, qualifier Q>
 	template<length_t L, typename T, qualifier Q>
-	GLM_FUNC_QUALIFIER vec<L, T, Q> fclamp(vec<L, T, Q> const& x, vec<L, T, Q> const& minVal, vec<L, T, Q> const& maxVal)
+	GLM_FUNC_QUALIFIER vec<L, T, Q> fmax(vec<L, T, Q> const& a, vec<L, T, Q> const& b, vec<L, T, Q> const& c, vec<L, T, Q> const& d)
 	{
 	{
-		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fclamp' only accept floating-point inputs");
-		return fmin(fmax(x, minVal), maxVal);
+		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'fmax' only accept floating-point inputs");
+		return fmax(fmax(a, b), fmax(c, d));
 	}
 	}
 }//namespace glm
 }//namespace glm

+ 0 - 1
test/ext/ext_scalar_common.cpp

@@ -2,7 +2,6 @@
 #include <glm/ext/scalar_constants.hpp>
 #include <glm/ext/scalar_constants.hpp>
 #include <glm/ext/scalar_relational.hpp>
 #include <glm/ext/scalar_relational.hpp>
 #include <glm/common.hpp>
 #include <glm/common.hpp>
-#include <algorithm>
 
 
 template <typename T>
 template <typename T>
 static int test_min()
 static int test_min()

+ 218 - 0
test/ext/ext_vector_common.cpp

@@ -1,4 +1,13 @@
 #include <glm/ext/vector_common.hpp>
 #include <glm/ext/vector_common.hpp>
+#include <glm/ext/vector_bool1.hpp>
+#include <glm/ext/vector_bool1_precision.hpp>
+#include <glm/ext/vector_bool2.hpp>
+#include <glm/ext/vector_bool2_precision.hpp>
+#include <glm/ext/vector_bool3.hpp>
+#include <glm/ext/vector_bool3_precision.hpp>
+#include <glm/ext/vector_bool4.hpp>
+#include <glm/ext/vector_bool4_precision.hpp>
+
 #include <glm/ext/vector_float1.hpp>
 #include <glm/ext/vector_float1.hpp>
 #include <glm/ext/vector_float1_precision.hpp>
 #include <glm/ext/vector_float1_precision.hpp>
 #include <glm/ext/vector_float2.hpp>
 #include <glm/ext/vector_float2.hpp>
@@ -15,10 +24,219 @@
 #include <glm/ext/vector_double3_precision.hpp>
 #include <glm/ext/vector_double3_precision.hpp>
 #include <glm/ext/vector_double4.hpp>
 #include <glm/ext/vector_double4.hpp>
 #include <glm/ext/vector_double4_precision.hpp>
 #include <glm/ext/vector_double4_precision.hpp>
+#include <glm/ext/vector_relational.hpp>
+#include <glm/ext/scalar_constants.hpp>
+#include <glm/vector_relational.hpp>
+#include <glm/common.hpp>
+
+template <typename vecType>
+static int test_min()
+{
+	typedef typename vecType::value_type T;
+
+	int Error = 0;
+
+	vecType const N(static_cast<T>(0));
+	vecType const B(static_cast<T>(1));
+	Error += glm::all(glm::equal(glm::min(N, B), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(B, N), N, glm::epsilon<T>())) ? 0 : 1;
+
+	vecType const C(static_cast<T>(2));
+	Error += glm::all(glm::equal(glm::min(N, B, C), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(B, N, C), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(C, N, B), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(C, B, N), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(B, C, N), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(N, C, B), N, glm::epsilon<T>())) ? 0 : 1;
+
+	vecType const D(static_cast<T>(3));
+	Error += glm::all(glm::equal(glm::min(D, N, B, C), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(B, D, N, C), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(C, N, D, B), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(C, B, D, N), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(B, C, N, D), N, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::min(N, C, B, D), N, glm::epsilon<T>())) ? 0 : 1;
+
+	return Error;
+}
+
+template <typename vecType>
+static int test_min_nan()
+{
+	typedef typename vecType::value_type T;
+
+	int Error = 0;
+
+	vecType const A(static_cast<T>(0));
+	vecType const B(static_cast<T>(1));
+	vecType const N(A / A);
+	Error += glm::all(glm::isnan(glm::min(N, B))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::min(B, N))) ? 0 : 1;
+
+	vecType const C(static_cast<T>(2));
+	Error += glm::all(glm::isnan(glm::min(N, B, C))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::min(B, N, C))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::min(C, N, B))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::min(C, B, N))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::min(B, C, N))) ? 0 : 1;
+	Error += glm::all(glm::isnan(glm::min(N, C, B))) ? 0 : 1;
+
+	vecType const D(static_cast<T>(3));
+	Error += !glm::all(glm::isnan(glm::min(D, N, B, C))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::min(B, D, N, C))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::min(C, N, D, B))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::min(C, B, D, N))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::min(B, C, N, D))) ? 0 : 1;
+	Error += glm::all(glm::isnan(glm::min(N, C, B, D))) ? 0 : 1;
+
+	return Error;
+}
+
+template <typename vecType>
+static int test_max()
+{
+	typedef typename vecType::value_type T;
+
+	int Error = 0;
+
+	vecType const N(static_cast<T>(0));
+	vecType const B(static_cast<T>(1));
+	Error += glm::all(glm::equal(glm::max(N, B), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(B, N), B, glm::epsilon<T>())) ? 0 : 1;
+
+	vecType const C(static_cast<T>(2));
+	Error += glm::all(glm::equal(glm::max(N, B, C), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(B, N, C), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(C, N, B), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(C, B, N), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(B, C, N), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(N, C, B), C, glm::epsilon<T>())) ? 0 : 1;
+
+	vecType const D(static_cast<T>(3));
+	Error += glm::all(glm::equal(glm::max(D, N, B, C), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(B, D, N, C), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(C, N, D, B), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(C, B, D, N), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(B, C, N, D), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::max(N, C, B, D), D, glm::epsilon<T>())) ? 0 : 1;
+
+	return Error;
+}
+
+template <typename vecType>
+static int test_max_nan()
+{
+	typedef typename vecType::value_type T;
+
+	int Error = 0;
+
+	vecType const A(static_cast<T>(0));
+	vecType const B(static_cast<T>(1));
+	vecType const N(A / A);
+	
+	Error += glm::all(glm::isnan(glm::max(N, B))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::max(B, N))) ? 0 : 1;
+
+	vecType const C(static_cast<T>(2));
+	Error += glm::all(glm::isnan(glm::max(N, B, C))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::max(B, N, C))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::max(C, N, B))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::max(C, B, N))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::max(B, C, N))) ? 0 : 1;
+	Error += glm::all(glm::isnan(glm::max(N, C, B))) ? 0 : 1;
+
+	vecType const D(static_cast<T>(3));
+	Error += !glm::all(glm::isnan(glm::max(D, N, B, C))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::max(B, D, N, C))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::max(C, N, D, B))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::max(C, B, D, N))) ? 0 : 1;
+	Error += !glm::all(glm::isnan(glm::max(B, C, N, D))) ? 0 : 1;
+	Error += glm::all(glm::isnan(glm::max(N, C, B, D))) ? 0 : 1;
+
+	return Error;
+}
+
+template <typename vecType>
+static int test_fmin()
+{
+	typedef typename vecType::value_type T;
+
+	int Error = 0;
+
+	vecType const A(static_cast<T>(0));
+	vecType const B(static_cast<T>(1));
+	Error += glm::all(glm::equal(glm::fmin(A / A, B), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(B, A / A), B, glm::epsilon<T>())) ? 0 : 1;
+
+	vecType const C(static_cast<T>(2));
+	Error += glm::all(glm::equal(glm::fmin(A / A, B, C), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(B, A / A, C), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(C, A / A, B), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(C, B, A / A), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(B, C, A / A), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(A / A, C, B), B, glm::epsilon<T>())) ? 0 : 1;
+
+	vecType const D(static_cast<T>(3));
+	Error += glm::all(glm::equal(glm::fmin(D, A / A, B, C), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(B, D, A / A, C), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(C, A / A, D, B), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(C, B, D, A / A), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(B, C, A / A, D), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmin(A / A, C, B, D), B, glm::epsilon<T>())) ? 0 : 1;
+
+	return Error;
+}
+
+template <typename vecType>
+static int test_fmax()
+{
+	typedef typename vecType::value_type T;
+
+	int Error = 0;
+
+	vecType const A(static_cast<T>(0));
+	vecType const B(static_cast<T>(1));
+	Error += glm::all(glm::equal(glm::fmax(A / A, B), B, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(B, A / A), B, glm::epsilon<T>())) ? 0 : 1;
+
+	vecType const C(static_cast<T>(2));
+	Error += glm::all(glm::equal(glm::fmax(A / A, B, C), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(B, A / A, C), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(C, A / A, B), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(C, B, A / A), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(B, C, A / A), C, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(A / A, C, B), C, glm::epsilon<T>())) ? 0 : 1;
+
+	vecType const D(static_cast<T>(3));
+	Error += glm::all(glm::equal(glm::fmax(D, A / A, B, C), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(B, D, A / A, C), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(C, A / A, D, B), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(C, B, D, A / A), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(B, C, A / A, D), D, glm::epsilon<T>())) ? 0 : 1;
+	Error += glm::all(glm::equal(glm::fmax(A / A, C, B, D), D, glm::epsilon<T>())) ? 0 : 1;
+
+	return Error;
+}
 
 
 int main()
 int main()
 {
 {
 	int Error = 0;
 	int Error = 0;
 
 
+	Error += test_min<glm::vec3>();
+	Error += test_min<glm::vec2>();
+	Error += test_min_nan<glm::vec3>();
+	Error += test_min_nan<glm::vec2>();
+
+	Error += test_max<glm::vec3>();
+	Error += test_max<glm::vec2>();
+	Error += test_max_nan<glm::vec3>();
+	Error += test_max_nan<glm::vec2>();
+
+	Error += test_fmin<glm::vec3>();
+	Error += test_fmin<glm::vec2>();
+
+	Error += test_fmax<glm::vec3>();
+	Error += test_fmax<glm::vec2>();
+
 	return Error;
 	return Error;
 }
 }