1/// @ref gtx_component_wise
2/// @file glm/gtx/component_wise.inl
3
4#include <limits>
5
6namespace glm{
7namespace detail
8{
9	template <typename T, typename floatType, precision P, template <typename, precision> class vecType, bool isInteger, bool signedType>
10	struct compute_compNormalize
11	{};
12
13	template <typename T, typename floatType, precision P, template <typename, precision> class vecType>
14	struct compute_compNormalize<T, floatType, P, vecType, true, true>
15	{
16		GLM_FUNC_QUALIFIER static vecType<floatType, P> call(vecType<T, P> const & v)
17		{
18			floatType const Min = static_cast<floatType>(std::numeric_limits<T>::min());
19			floatType const Max = static_cast<floatType>(std::numeric_limits<T>::max());
20			return (vecType<floatType, P>(v) - Min) / (Max - Min) * static_cast<floatType>(2) - static_cast<floatType>(1);
21		}
22	};
23
24	template <typename T, typename floatType, precision P, template <typename, precision> class vecType>
25	struct compute_compNormalize<T, floatType, P, vecType, true, false>
26	{
27		GLM_FUNC_QUALIFIER static vecType<floatType, P> call(vecType<T, P> const & v)
28		{
29			return vecType<floatType, P>(v) / static_cast<floatType>(std::numeric_limits<T>::max());
30		}
31	};
32
33	template <typename T, typename floatType, precision P, template <typename, precision> class vecType>
34	struct compute_compNormalize<T, floatType, P, vecType, false, true>
35	{
36		GLM_FUNC_QUALIFIER static vecType<floatType, P> call(vecType<T, P> const & v)
37		{
38			return v;
39		}
40	};
41
42	template <typename T, typename floatType, precision P, template <typename, precision> class vecType, bool isInteger, bool signedType>
43	struct compute_compScale
44	{};
45
46	template <typename T, typename floatType, precision P, template <typename, precision> class vecType>
47	struct compute_compScale<T, floatType, P, vecType, true, true>
48	{
49		GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<floatType, P> const & v)
50		{
51			floatType const Max = static_cast<floatType>(std::numeric_limits<T>::max()) + static_cast<floatType>(0.5);
52			vecType<floatType, P> const Scaled(v * Max);
53			vecType<T, P> const Result(Scaled - static_cast<floatType>(0.5));
54			return Result;
55		}
56	};
57
58	template <typename T, typename floatType, precision P, template <typename, precision> class vecType>
59	struct compute_compScale<T, floatType, P, vecType, true, false>
60	{
61		GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<floatType, P> const & v)
62		{
63			return vecType<T, P>(vecType<floatType, P>(v) * static_cast<floatType>(std::numeric_limits<T>::max()));
64		}
65	};
66
67	template <typename T, typename floatType, precision P, template <typename, precision> class vecType>
68	struct compute_compScale<T, floatType, P, vecType, false, true>
69	{
70		GLM_FUNC_QUALIFIER static vecType<T, P> call(vecType<floatType, P> const & v)
71		{
72			return v;
73		}
74	};
75}//namespace detail
76
77	template <typename floatType, typename T, precision P, template <typename, precision> class vecType>
78	GLM_FUNC_QUALIFIER vecType<floatType, P> compNormalize(vecType<T, P> const & v)
79	{
80		GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "'compNormalize' accepts only floating-point types for 'floatType' template parameter");
81
82		return detail::compute_compNormalize<T, floatType, P, vecType, std::numeric_limits<T>::is_integer, std::numeric_limits<T>::is_signed>::call(v);
83	}
84
85	template <typename T, typename floatType, precision P, template <typename, precision> class vecType>
86	GLM_FUNC_QUALIFIER vecType<T, P> compScale(vecType<floatType, P> const & v)
87	{
88		GLM_STATIC_ASSERT(std::numeric_limits<floatType>::is_iec559, "'compScale' accepts only floating-point types for 'floatType' template parameter");
89
90		return detail::compute_compScale<T, floatType, P, vecType, std::numeric_limits<T>::is_integer, std::numeric_limits<T>::is_signed>::call(v);
91	}
92
93	template <typename T, precision P, template <typename, precision> class vecType>
94	GLM_FUNC_QUALIFIER T compAdd(vecType<T, P> const & v)
95	{
96		T Result(0);
97		for(length_t i = 0, n = v.length(); i < n; ++i)
98			Result += v[i];
99		return Result;
100	}
101
102	template <typename T, precision P, template <typename, precision> class vecType>
103	GLM_FUNC_QUALIFIER T compMul(vecType<T, P> const & v)
104	{
105		T Result(1);
106		for(length_t i = 0, n = v.length(); i < n; ++i)
107			Result *= v[i];
108		return Result;
109	}
110
111	template <typename T, precision P, template <typename, precision> class vecType>
112	GLM_FUNC_QUALIFIER T compMin(vecType<T, P> const & v)
113	{
114		T Result(v[0]);
115		for(length_t i = 1, n = v.length(); i < n; ++i)
116			Result = min(Result, v[i]);
117		return Result;
118	}
119
120	template <typename T, precision P, template <typename, precision> class vecType>
121	GLM_FUNC_QUALIFIER T compMax(vecType<T, P> const & v)
122	{
123		T Result(v[0]);
124		for(length_t i = 1, n = v.length(); i < n; ++i)
125			Result = max(Result, v[i]);
126		return Result;
127	}
128}//namespace glm
129