1/// @ref gtx_common
2/// @file glm/gtx/common.inl
3
4#include <cmath>
5
6namespace glm{
7namespace detail
8{
9	template <typename T, precision P, template <class, precision> class vecType, bool isFloat = true>
10	struct compute_fmod
11	{
12		GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & a, vecType<T, P> const & b)
13		{
14			return detail::functor2<T, P, vecType>::call(std::fmod, a, b);
15		}
16	};
17
18	template <typename T, precision P, template <class, precision> class vecType>
19	struct compute_fmod<T, P, vecType, false>
20	{
21		GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<T, P> const & a, vecType<T, P> const & b)
22		{
23			return a % b;
24		}
25	};
26}//namespace detail
27
28	template <typename T>
29	GLM_FUNC_QUALIFIER bool isdenormal(T const & x)
30	{
31		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isdenormal' only accept floating-point inputs");
32
33#		if GLM_HAS_CXX11_STL
34			return std::fpclassify(x) == FP_SUBNORMAL;
35#		else
36			return x != static_cast<T>(0) && std::fabs(x) < std::numeric_limits<T>::min();
37#		endif
38	}
39
40	template <typename T, precision P>
41	GLM_FUNC_QUALIFIER typename tvec1<T, P>::bool_type isdenormal
42	(
43		tvec1<T, P> const & x
44	)
45	{
46		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isdenormal' only accept floating-point inputs");
47
48		return typename tvec1<T, P>::bool_type(
49			isdenormal(x.x));
50	}
51
52	template <typename T, precision P>
53	GLM_FUNC_QUALIFIER typename tvec2<T, P>::bool_type isdenormal
54	(
55		tvec2<T, P> const & x
56	)
57	{
58		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isdenormal' only accept floating-point inputs");
59
60		return typename tvec2<T, P>::bool_type(
61			isdenormal(x.x),
62			isdenormal(x.y));
63	}
64
65	template <typename T, precision P>
66	GLM_FUNC_QUALIFIER typename tvec3<T, P>::bool_type isdenormal
67	(
68		tvec3<T, P> const & x
69	)
70	{
71		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isdenormal' only accept floating-point inputs");
72
73		return typename tvec3<T, P>::bool_type(
74			isdenormal(x.x),
75			isdenormal(x.y),
76			isdenormal(x.z));
77	}
78
79	template <typename T, precision P>
80	GLM_FUNC_QUALIFIER typename tvec4<T, P>::bool_type isdenormal
81	(
82		tvec4<T, P> const & x
83	)
84	{
85		GLM_STATIC_ASSERT(std::numeric_limits<T>::is_iec559, "'isdenormal' only accept floating-point inputs");
86
87		return typename tvec4<T, P>::bool_type(
88			isdenormal(x.x),
89			isdenormal(x.y),
90			isdenormal(x.z),
91			isdenormal(x.w));
92	}
93
94	// fmod
95	template <typename genType>
96	GLM_FUNC_QUALIFIER genType fmod(genType x, genType y)
97	{
98		return fmod(tvec1<genType>(x), y).x;
99	}
100
101	template <typename T, precision P, template <typename, precision> class vecType>
102	GLM_FUNC_QUALIFIER vecType<T, P> fmod(vecType<T, P> const & x, T y)
103	{
104		return detail::compute_fmod<T, P, vecType, std::numeric_limits<T>::is_iec559>::call(x, vecType<T, P>(y));
105	}
106
107	template <typename T, precision P, template <typename, precision> class vecType>
108	GLM_FUNC_QUALIFIER vecType<T, P> fmod(vecType<T, P> const & x, vecType<T, P> const & y)
109	{
110		return detail::compute_fmod<T, P, vecType, std::numeric_limits<T>::is_iec559>::call(x, y);
111	}
112}//namespace glm
113