浏览代码

Added precision template parameter

Christophe Riccio 12 年之前
父节点
当前提交
c14e2d7fbc
共有 100 个文件被更改,包括 10119 次插入9379 次删除
  1. 722 722
      glm/core/_swizzle_func.hpp
  2. 108 108
      glm/core/_vectorize.hpp
  3. 41 40
      glm/core/func_common.hpp
  4. 258 258
      glm/core/func_common.inl
  5. 15 15
      glm/core/func_geometric.hpp
  6. 58 67
      glm/core/func_geometric.inl
  7. 163 163
      glm/core/func_integer.inl
  8. 27 27
      glm/core/func_matrix.hpp
  9. 124 124
      glm/core/func_matrix.inl
  10. 3 3
      glm/core/func_noise.hpp
  11. 175 170
      glm/core/func_noise.inl
  12. 11 11
      glm/core/func_packing.hpp
  13. 36 36
      glm/core/func_packing.inl
  14. 1 1
      glm/core/func_vector_relational.hpp
  15. 67 67
      glm/core/func_vector_relational.inl
  16. 2 2
      glm/core/intrinsic_matrix.inl
  17. 54 0
      glm/core/precision.hpp
  18. 0 0
      glm/core/precision.inl
  19. 22 0
      glm/core/type_half.hpp
  20. 353 58
      glm/core/type_mat.hpp
  21. 125 125
      glm/core/type_mat2x2.hpp
  22. 210 210
      glm/core/type_mat2x2.inl
  23. 102 102
      glm/core/type_mat2x3.hpp
  24. 200 200
      glm/core/type_mat2x3.inl
  25. 101 101
      glm/core/type_mat2x4.hpp
  26. 220 220
      glm/core/type_mat2x4.inl
  27. 108 108
      glm/core/type_mat3x2.hpp
  28. 200 200
      glm/core/type_mat3x2.inl
  29. 147 147
      glm/core/type_mat3x3.hpp
  30. 247 247
      glm/core/type_mat3x3.inl
  31. 102 102
      glm/core/type_mat3x4.hpp
  32. 201 201
      glm/core/type_mat3x4.inl
  33. 98 98
      glm/core/type_mat4x2.hpp
  34. 210 208
      glm/core/type_mat4x2.inl
  35. 108 108
      glm/core/type_mat4x3.hpp
  36. 200 200
      glm/core/type_mat4x3.inl
  37. 130 130
      glm/core/type_mat4x4.hpp
  38. 254 254
      glm/core/type_mat4x4.inl
  39. 57 55
      glm/core/type_vec.hpp
  40. 41 47
      glm/core/type_vec1.hpp
  41. 289 294
      glm/core/type_vec1.inl
  42. 56 63
      glm/core/type_vec2.hpp
  43. 304 312
      glm/core/type_vec2.inl
  44. 62 69
      glm/core/type_vec3.hpp
  45. 293 301
      glm/core/type_vec3.inl
  46. 72 79
      glm/core/type_vec4.hpp
  47. 249 251
      glm/core/type_vec4.inl
  48. 115 111
      glm/fwd.hpp
  49. 1 0
      glm/glm.hpp
  50. 84 84
      glm/gtc/epsilon.inl
  51. 381 131
      glm/gtc/half_float.hpp
  52. 165 165
      glm/gtc/half_float.inl
  53. 73 73
      glm/gtc/matrix_integer.hpp
  54. 50 50
      glm/gtc/matrix_inverse.inl
  55. 84 84
      glm/gtc/matrix_transform.hpp
  56. 122 120
      glm/gtc/matrix_transform.inl
  57. 429 374
      glm/gtc/noise.inl
  58. 142 146
      glm/gtc/quaternion.hpp
  59. 244 244
      glm/gtc/quaternion.inl
  60. 13 13
      glm/gtc/random.hpp
  61. 16 12
      glm/gtc/random.inl
  62. 54 48
      glm/gtc/swizzle.hpp
  63. 29 29
      glm/gtc/swizzle.inl
  64. 105 105
      glm/gtc/type_precision.hpp
  65. 16 16
      glm/gtc/type_ptr.hpp
  66. 108 108
      glm/gtc/type_ptr.inl
  67. 114 114
      glm/gtx/associated_min_max.inl
  68. 124 124
      glm/gtx/bit.inl
  69. 4 4
      glm/gtx/closest_point.hpp
  70. 19 19
      glm/gtx/color_cast.hpp
  71. 74 74
      glm/gtx/color_cast.inl
  72. 14 14
      glm/gtx/color_space.inl
  73. 13 13
      glm/gtx/compatibility.hpp
  74. 186 101
      glm/gtx/dual_quaternion.hpp
  75. 137 137
      glm/gtx/dual_quaternion.inl
  76. 51 51
      glm/gtx/euler_angles.hpp
  77. 127 127
      glm/gtx/euler_angles.inl
  78. 9 9
      glm/gtx/fast_exponential.inl
  79. 11 11
      glm/gtx/gradient_paint.hpp
  80. 20 20
      glm/gtx/gradient_paint.inl
  81. 6 6
      glm/gtx/handed_coordinate_space.hpp
  82. 6 6
      glm/gtx/handed_coordinate_space.inl
  83. 10 10
      glm/gtx/inertia.hpp
  84. 18 18
      glm/gtx/inertia.inl
  85. 12 12
      glm/gtx/integer.inl
  86. 4 4
      glm/gtx/matrix_cross_product.hpp
  87. 6 6
      glm/gtx/matrix_cross_product.inl
  88. 26 26
      glm/gtx/matrix_interpolation.hpp
  89. 34 25
      glm/gtx/matrix_interpolation.inl
  90. 36 36
      glm/gtx/matrix_major_storage.hpp
  91. 48 48
      glm/gtx/matrix_major_storage.inl
  92. 21 21
      glm/gtx/matrix_query.hpp
  93. 37 37
      glm/gtx/matrix_query.inl
  94. 20 20
      glm/gtx/norm.hpp
  95. 32 32
      glm/gtx/norm.inl
  96. 4 4
      glm/gtx/normal.hpp
  97. 4 4
      glm/gtx/normal.inl
  98. 14 11
      glm/gtx/optimum_pow.hpp
  99. 16 13
      glm/gtx/optimum_pow.inl
  100. 5 5
      glm/gtx/orthonormalize.hpp

+ 722 - 722
glm/core/_swizzle_func.hpp

@@ -29,758 +29,758 @@
 #ifndef glm_core_swizzle_func
 #define glm_core_swizzle_func
 
-#define GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B) \
-	SWIZZLED_TYPE<TMPL_TYPE> A ## B() CONST \
-	{ \
-		return SWIZZLED_TYPE<TMPL_TYPE>(this->A, this->B); \
+#define GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B)	\
+	SWIZZLED_TYPE<TMPL_TYPE, PRECISION> A ## B() CONST												\
+	{																								\
+		return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B);								\
 	}
 
-#define GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C) \
-	SWIZZLED_TYPE<TMPL_TYPE> A ## B ## C() CONST \
-	{ \
-		return SWIZZLED_TYPE<TMPL_TYPE>(this->A, this->B, this->C); \
+#define GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C)		\
+	SWIZZLED_TYPE<TMPL_TYPE, PRECISION> A ## B ## C() CONST												\
+	{																									\
+		return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C);							\
 	}
 
-#define GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D) \
-	SWIZZLED_TYPE<TMPL_TYPE> A ## B ## C ## D() CONST \
-	{ \
-		return SWIZZLED_TYPE<TMPL_TYPE>(this->A, this->B, this->C, this->D); \
+#define GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D)	\
+	SWIZZLED_TYPE<TMPL_TYPE, PRECISION> A ## B ## C ## D() CONST										\
+	{																									\
+		return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C, this->D);					\
 	}
 
-#define GLM_SWIZZLE_GEN_VEC2_ENTRY_DEF(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B) \
-	template <typename TMPL_TYPE> \
-	SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE>::A ## B() CONST \
-	{ \
-		return SWIZZLED_TYPE<TMPL_TYPE>(this->A, this->B); \
+#define GLM_SWIZZLE_GEN_VEC2_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B)	\
+	template <typename TMPL_TYPE>																		\
+	SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE, PRECISION>::A ## B() CONST							\
+	{																									\
+		return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B);									\
 	}
 
-#define GLM_SWIZZLE_GEN_VEC3_ENTRY_DEF(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C) \
-	template <typename TMPL_TYPE> \
-	SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE>::A ## B ## C() CONST \
-	{ \
-		return SWIZZLED_TYPE<TMPL_TYPE>(this->A, this->B, this->C); \
+#define GLM_SWIZZLE_GEN_VEC3_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C)		\
+	template <typename TMPL_TYPE>																			\
+	SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE, PRECISION>::A ## B ## C() CONST							\
+	{																										\
+		return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C);								\
 	}
 
-#define GLM_SWIZZLE_GEN_VEC4_ENTRY_DEF(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D) \
-	template <typename TMPL_TYPE> \
-	SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE>::A ## B ## C ## D() CONST \
-	{ \
-		return SWIZZLED_TYPE<TMPL_TYPE>(this->A, this->B, this->C, this->D); \
+#define GLM_SWIZZLE_GEN_VEC4_ENTRY_DEF(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, CONST, A, B, C, D)	\
+	template <typename TMPL_TYPE>																			\
+	SWIZZLED_TYPE<TMPL_TYPE> CLASS_TYPE<TMPL_TYPE, PRECISION>::A ## B ## C ## D() CONST						\
+	{																										\
+		return SWIZZLED_TYPE<TMPL_TYPE, PRECISION>(this->A, this->B, this->C, this->D);						\
 	}
 
 #define GLM_MUTABLE
 
-#define GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A)
+#define GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A)
 
-#define GLM_SWIZZLE_GEN_REF_FROM_VEC2(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE) \
-	GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, x, y) \
-	GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, r, g) \
-	GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, s, t)
+#define GLM_SWIZZLE_GEN_REF_FROM_VEC2(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE) \
+	GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, x, y) \
+	GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, r, g) \
+	GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, s, t)
 
 //GLM_SWIZZLE_GEN_REF_FROM_VEC2(valType, detail::vec2, detail::ref2)
 
-#define GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B)
-
-#define GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B, A)
-
-#define GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C)
-
-#define GLM_SWIZZLE_GEN_REF_FROM_VEC3(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE) \
-	GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, x, y, z) \
-	GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, r, g, b) \
-	GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, s, t, q)
+#define GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B)
+
+#define GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B, A)
+
+#define GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_REF3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_REF2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C)
+
+#define GLM_SWIZZLE_GEN_REF_FROM_VEC3(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE) \
+	GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, x, y, z) \
+	GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, r, g, b) \
+	GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, s, t, q)
 
 //GLM_SWIZZLE_GEN_REF_FROM_VEC3(valType, detail::vec3, detail::ref2, detail::ref3)
 
-#define GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, D) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, D) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, D) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, C)
-
-#define GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B)
-
-#define GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C, A)
-
-#define GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D)
-
-#define GLM_SWIZZLE_GEN_REF_FROM_VEC4(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
-	GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z, w) \
-	GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b, a) \
-	GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, q, p)
+#define GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, A, D) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, B, D) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, C, D) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, GLM_MUTABLE, D, C)
+
+#define GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B)
+
+#define GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, C, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, C, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , B, A, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, B, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , C, A, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, , D, B, C, A)
+
+#define GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_REF2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_REF3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_REF4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D)
+
+#define GLM_SWIZZLE_GEN_REF_FROM_VEC4(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
+	GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z, w) \
+	GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b, a) \
+	GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, q, p)
 
 //GLM_SWIZZLE_GEN_REF_FROM_VEC4(valType, detail::vec4, detail::ref2, detail::ref3, detail::ref4)
 
-#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B)
-
-#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B)
-
-#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B)
-
-#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B) \
-	GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B)
-
-#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
-	GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y) \
-	GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g) \
-	GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t)
+#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B)
+
+#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B)
+
+#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B)
+
+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B) \
+	GLM_SWIZZLE_GEN_VEC2_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_FROM_VEC2_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B)
+
+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC2(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE)			\
+	GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y)	\
+	GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g)	\
+	GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t)
 
 //GLM_SWIZZLE_GEN_VEC_FROM_VEC2(valType, detail::vec2, detail::vec2, detail::vec3, detail::vec4)
 
-#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C)
-
-#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C)
-
-#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, C)
-
-#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C)
-
-#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
-	GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z) \
-	GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b) \
-	GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, q)
+#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C)
+
+#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C)
+
+#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, C)
+
+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC2_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_FROM_VEC3_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C)
+
+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC3(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
+	GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z) \
+	GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b) \
+	GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, q)
 
 //GLM_SWIZZLE_GEN_VEC_FROM_VEC3(valType, detail::vec3, detail::vec2, detail::vec3, detail::vec4)
 
-#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C) \
-	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D)
-
-#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C) \
-	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D)
-
-#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, A) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, B) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, C) \
-	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, D)
-
-#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C, D) \
-	GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D)
-
-#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
-	GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z, w) \
-	GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b, a) \
-	GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, q, p)
+#define GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C) \
+	GLM_SWIZZLE_GEN_VEC2_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D)
+
+#define GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C) \
+	GLM_SWIZZLE_GEN_VEC3_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D)
+
+#define GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, A, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, B, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, C, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, A, D, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, A, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, B, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, C, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, B, D, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, A, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, B, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, C, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, C, D, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, A, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, B, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, C, D, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, A, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, B, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, A) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, B) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, C) \
+	GLM_SWIZZLE_GEN_VEC4_ENTRY(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_TYPE, const, D, D, D, D)
+
+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC2_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC3_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC3_TYPE, A, B, C, D) \
+	GLM_SWIZZLE_GEN_VEC4_FROM_VEC4_SWIZZLE(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC4_TYPE, A, B, C, D)
+
+#define GLM_SWIZZLE_GEN_VEC_FROM_VEC4(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE) \
+	GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, x, y, z, w) \
+	GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, r, g, b, a) \
+	GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(TMPL_TYPE, PRECISION, CLASS_TYPE, SWIZZLED_VEC2_TYPE, SWIZZLED_VEC3_TYPE, SWIZZLED_VEC4_TYPE, s, t, q, p)
 
 //GLM_SWIZZLE_GEN_VEC_FROM_VEC4(valType, detail::vec4, detail::vec2, detail::vec3, detail::vec4)
 

+ 108 - 108
glm/core/_vectorize.hpp

@@ -29,136 +29,136 @@
 #ifndef GLM_CORE_DETAIL_INCLUDED
 #define GLM_CORE_DETAIL_INCLUDED
 
-#define VECTORIZE2_VEC(func) \
-	template <typename T> \
-	GLM_FUNC_QUALIFIER detail::tvec2<T> func( \
-		detail::tvec2<T> const & v) \
-	{ \
-		return detail::tvec2<T>( \
-			func(v.x), \
-			func(v.y)); \
+#define VECTORIZE2_VEC(func)						\
+	template <typename T, precision P>				\
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> func(	\
+		detail::tvec2<T, P> const & v)				\
+	{												\
+		return detail::tvec2<T, P>(					\
+			func(v.x),								\
+			func(v.y));								\
 	}
 
-#define VECTORIZE3_VEC(func) \
-	template <typename T> \
-	GLM_FUNC_QUALIFIER detail::tvec3<T> func( \
-		detail::tvec3<T> const & v) \
-	{ \
-		return detail::tvec3<T>( \
-			func(v.x), \
-			func(v.y), \
-			func(v.z)); \
+#define VECTORIZE3_VEC(func)						\
+	template <typename T, precision P>				\
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> func(	\
+		detail::tvec3<T, P> const & v)				\
+	{												\
+		return detail::tvec3<T, P>(					\
+			func(v.x),								\
+			func(v.y),								\
+			func(v.z));								\
 	}
 
-#define VECTORIZE4_VEC(func) \
-	template <typename T> \
-	GLM_FUNC_QUALIFIER detail::tvec4<T> func( \
-		detail::tvec4<T> const & v) \
-	{ \
-		return detail::tvec4<T>( \
-			func(v.x), \
-			func(v.y), \
-			func(v.z), \
-			func(v.w)); \
+#define VECTORIZE4_VEC(func)						\
+	template <typename T, precision P>				\
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> func(	\
+		detail::tvec4<T, P> const & v)				\
+	{												\
+		return detail::tvec4<T, P>(					\
+			func(v.x),								\
+			func(v.y),								\
+			func(v.z),								\
+			func(v.w));								\
 	}
 
-#define VECTORIZE_VEC(func) \
-	VECTORIZE2_VEC(func) \
-	VECTORIZE3_VEC(func) \
+#define VECTORIZE_VEC(func)		\
+	VECTORIZE2_VEC(func)		\
+	VECTORIZE3_VEC(func)		\
 	VECTORIZE4_VEC(func)
 
-#define VECTORIZE2_VEC_SCA(func) \
-	template <typename T> \
-	GLM_FUNC_QUALIFIER detail::tvec2<T> func \
-	( \
-		detail::tvec2<T> const & x,  \
-		typename detail::tvec2<T>::value_type const & y \
-	) \
-	{ \
-		return detail::tvec2<T>( \
-			func(x.x, y), \
-			func(x.y, y)); \
+#define VECTORIZE2_VEC_SCA(func)							\
+	template <typename T, precision P>						\
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> func				\
+	(														\
+		detail::tvec2<T, P> const & x,						\
+		typename detail::tvec2<T, P>::value_type const & y	\
+	)														\
+	{														\
+		return detail::tvec2<T, P>(							\
+			func(x.x, y),									\
+			func(x.y, y));									\
 	}
 
-#define VECTORIZE3_VEC_SCA(func) \
-	template <typename T> \
-	GLM_FUNC_QUALIFIER detail::tvec3<T> func \
-	( \
-		detail::tvec3<T> const & x,  \
-		typename detail::tvec3<T>::value_type const & y \
-	) \
-	{ \
-		return detail::tvec3<T>( \
-			func(x.x, y), \
-			func(x.y, y), \
-			func(x.z, y)); \
+#define VECTORIZE3_VEC_SCA(func)							\
+	template <typename T, precision P>						\
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> func				\
+	(														\
+		detail::tvec3<T, P> const & x,						\
+		typename detail::tvec3<T, P>::value_type const & y	\
+	)														\
+	{														\
+		return detail::tvec3<T, P>(							\
+			func(x.x, y),									\
+			func(x.y, y),									\
+			func(x.z, y));									\
 	}
 
-#define VECTORIZE4_VEC_SCA(func) \
-	template <typename T> \
-	GLM_FUNC_QUALIFIER detail::tvec4<T> func \
-	( \
-		detail::tvec4<T> const & x,  \
-		typename detail::tvec4<T>::value_type const & y \
-	) \
-	{ \
-		return detail::tvec4<T>( \
-			func(x.x, y), \
-			func(x.y, y), \
-			func(x.z, y), \
-			func(x.w, y)); \
+#define VECTORIZE4_VEC_SCA(func)							\
+	template <typename T, precision P>						\
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> func				\
+	(														\
+		detail::tvec4<T, P> const & x,						\
+		typename detail::tvec4<T, P>::value_type const & y	\
+	)														\
+	{														\
+		return detail::tvec4<T, P>(							\
+			func(x.x, y),									\
+			func(x.y, y),									\
+			func(x.z, y),									\
+			func(x.w, y));									\
 	}
 
-#define VECTORIZE_VEC_SCA(func) \
-	VECTORIZE2_VEC_SCA(func) \
-	VECTORIZE3_VEC_SCA(func) \
+#define VECTORIZE_VEC_SCA(func)		\
+	VECTORIZE2_VEC_SCA(func)		\
+	VECTORIZE3_VEC_SCA(func)		\
 	VECTORIZE4_VEC_SCA(func)
 
-#define VECTORIZE2_VEC_VEC(func) \
-	template <typename T> \
-	GLM_FUNC_QUALIFIER detail::tvec2<T> func \
-	( \
-		detail::tvec2<T> const & x,  \
-		detail::tvec2<T> const & y \
-	) \
-	{ \
-		return detail::tvec2<T>( \
-			func(x.x, y.x), \
-			func(x.y, y.y)); \
+#define VECTORIZE2_VEC_VEC(func)					\
+	template <typename T, precision P>				\
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> func		\
+	(												\
+		detail::tvec2<T, P> const & x,				\
+		detail::tvec2<T, P> const & y				\
+	)												\
+	{												\
+		return detail::tvec2<T, P>(					\
+			func(x.x, y.x),							\
+			func(x.y, y.y));						\
 	}
 
-#define VECTORIZE3_VEC_VEC(func) \
-	template <typename T> \
-	GLM_FUNC_QUALIFIER detail::tvec3<T> func \
-	( \
-		detail::tvec3<T> const & x,  \
-		detail::tvec3<T> const & y \
-	) \
-	{ \
-		return detail::tvec3<T>( \
-			func(x.x, y.x), \
-			func(x.y, y.y), \
-			func(x.z, y.z)); \
+#define VECTORIZE3_VEC_VEC(func)					\
+	template <typename T, precision P>				\
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> func		\
+	(												\
+		detail::tvec3<T, P> const & x,				\
+		detail::tvec3<T, P> const & y				\
+	)												\
+	{												\
+		return detail::tvec3<T, P>(					\
+			func(x.x, y.x),							\
+			func(x.y, y.y),							\
+			func(x.z, y.z));						\
 	}
 
-#define VECTORIZE4_VEC_VEC(func) \
-	template <typename T> \
-	GLM_FUNC_QUALIFIER detail::tvec4<T> func \
-	( \
-		detail::tvec4<T> const & x,  \
-		detail::tvec4<T> const & y \
-	) \
-	{ \
-		return detail::tvec4<T>( \
-			func(x.x, y.x), \
-			func(x.y, y.y), \
-			func(x.z, y.z), \
-			func(x.w, y.w)); \
+#define VECTORIZE4_VEC_VEC(func)				\
+	template <typename T, precision P>			\
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> func	\
+	(											\
+		detail::tvec4<T, P> const & x,			\
+		detail::tvec4<T, P> const & y			\
+	)											\
+	{											\
+		return detail::tvec4<T, P>(				\
+			func(x.x, y.x),						\
+			func(x.y, y.y),						\
+			func(x.z, y.z),						\
+			func(x.w, y.w));					\
 	}
 
-#define VECTORIZE_VEC_VEC(func) \
-	VECTORIZE2_VEC_VEC(func) \
-	VECTORIZE3_VEC_VEC(func) \
+#define VECTORIZE_VEC_VEC(func)		\
+	VECTORIZE2_VEC_VEC(func)		\
+	VECTORIZE3_VEC_VEC(func)		\
 	VECTORIZE4_VEC_VEC(func)
 
 namespace glm{

+ 41 - 40
glm/core/func_common.hpp

@@ -36,6 +36,7 @@
 #ifndef GLM_CORE_func_common
 #define GLM_CORE_func_common GLM_VERSION
 
+#include "setup.hpp"
 #include "_fixes.hpp"
 
 namespace glm
@@ -121,31 +122,31 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/fract.xml">GLSL fract man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType fract(genType const & x);
 
-	/// Modulus. Returns x - y * floor(x / y) 
+	/// Modulus. Returns x - y * floor(x / y)
 	/// for each component in x using the floating point value y.
 	///
 	/// @tparam genType Floating-point scalar or vector types.
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType mod(
-		genType const & x, 
+		genType const & x,
 		genType const & y);
 
-	/// Modulus. Returns x - y * floor(x / y) 
+	/// Modulus. Returns x - y * floor(x / y)
 	/// for each component in x using the floating point value y.
 	/// 
 	/// @tparam genType Floating-point scalar or vector types.
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/mod.xml">GLSL mod man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType mod(
-		genType const & x, 
+		genType const & x,
 		typename genType::value_type const & y);
 
 	/// Returns the fractional part of x and sets i to the integer
@@ -157,9 +158,9 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/modf.xml">GLSL modf man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType modf(
-		genType const & x, 
+		genType const & x,
 		genType & i);
 
 	/// Returns y if y < x; otherwise, it returns x.
@@ -168,14 +169,14 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/min.xml">GLSL min man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType min(
-		genType const & x, 
+		genType const & x,
 		genType const & y);
 
-	template <typename genType> 
+	template <typename genType>
 	genType min(
-		genType const & x, 
+		genType const & x,
 		typename genType::value_type const & y);
 
 	/// Returns y if x < y; otherwise, it returns x.
@@ -184,14 +185,14 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/max.xml">GLSL max man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType max(
-		genType const & x, 
+		genType const & x,
 		genType const & y);
 
-	template <typename genType> 
+	template <typename genType>
 	genType max(
-		genType const & x, 
+		genType const & x,
 		typename genType::value_type const & y);
 
 	/// Returns min(max(x, minVal), maxVal) for each component in x 
@@ -201,24 +202,24 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/clamp.xml">GLSL clamp man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType clamp(
-		genType const & x, 
-		genType const & minVal, 
-		genType const & maxVal); 
+		genType const & x,
+		genType const & minVal,
+		genType const & maxVal);
 
-	template <typename genType> 
+	template <typename genType>
 	genType clamp(
-		genType const & x, 
-		typename genType::value_type const & minVal, 
-		typename genType::value_type const & maxVal); 
+		genType const & x,
+		typename genType::value_type const & minVal,
+		typename genType::value_type const & maxVal);
 
-	/// If genTypeU is a floating scalar or vector: 
-	/// Returns x * (1.0 - a) + y * a, i.e., the linear blend of 
-	/// x and y using the floating-point value a. 
+	/// If genTypeU is a floating scalar or vector:
+	/// Returns x * (1.0 - a) + y * a, i.e., the linear blend of
+	/// x and y using the floating-point value a.
 	/// The value for a is not restricted to the range [0, 1].
 	/// 
-	/// If genTypeU is a boolean scalar or vector: 
+	/// If genTypeU is a boolean scalar or vector:
 	/// Selects which vector each returned component comes
 	/// from. For a component of <a> that is false, the
 	/// corresponding component of x is returned. For a
@@ -255,21 +256,21 @@ namespace glm
 	/// glm::dvec3 t = glm::mix(e, f, a); // Types of the third parameter is not required to match with the first and the second.
 	/// glm::vec4 u = glm::mix(g, h, r); // Interpolations can be perform per component with a vector for the last parameter.
 	/// @endcode
-	template <typename genTypeT, typename genTypeU> 
+	template <typename genTypeT, typename genTypeU>
 	genTypeT mix(genTypeT const & x, genTypeT const & y, genTypeU const & a);
 
 	//! Returns 0.0 if x < edge, otherwise it returns 1.0.
 	//! 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/step.xml">GLSL step man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType step(
-		genType const & edge, 
+		genType const & edge,
 		genType const & x);
 
-	template <typename genType> 
+	template <typename genType>
 	genType step(
-		typename genType::value_type const & edge, 
+		typename genType::value_type const & edge,
 		genType const & x);
 
 	/// Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and
@@ -286,16 +287,16 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/smoothstep.xml">GLSL smoothstep man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.3 Common Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType smoothstep(
-		genType const & edge0, 
-		genType const & edge1, 
+		genType const & edge0,
+		genType const & edge1,
 		genType const & x);
 
-	template <typename genType> 
+	template <typename genType>
 	genType smoothstep(
-		typename genType::value_type const & edge0, 
-		typename genType::value_type const & edge1, 
+		typename genType::value_type const & edge0,
+		typename genType::value_type const & edge1,
 		genType const & x);
 
 	/// Returns true if x holds a NaN (not a number)

文件差异内容过多而无法显示
+ 258 - 258
glm/core/func_common.inl


+ 15 - 15
glm/core/func_geometric.hpp

@@ -68,9 +68,9 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/dot.xml">GLSL dot man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	typename genType::value_type dot(
-		genType const & x, 
+		genType const & x,
 		genType const & y);
 
 	/// Returns the cross product of x and y.
@@ -79,16 +79,16 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/cross.xml">GLSL cross man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename valType> 
-	detail::tvec3<valType> cross(
-		detail::tvec3<valType> const & x, 
-		detail::tvec3<valType> const & y);
+	template <typename T, precision P>
+	detail::tvec3<T, P> cross(
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y);
 
 	/// Returns a vector in the same direction as x but with length of 1.
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/normalize.xml">GLSL normalize man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType normalize(
 		genType const & x);
 
@@ -98,10 +98,10 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/faceforward.xml">GLSL faceforward man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType faceforward(
-		genType const & N, 
-		genType const & I, 
+		genType const & N,
+		genType const & I,
 		genType const & Nref);
 
 	/// For the incident vector I and surface orientation N, 
@@ -111,9 +111,9 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/reflect.xml">GLSL reflect man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType reflect(
-		genType const & I, 
+		genType const & I,
 		genType const & N);
 
 	/// For the incident vector I and surface normal N, 
@@ -124,10 +124,10 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/refract.xml">GLSL refract man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.5 Geometric Functions</a>
-	template <typename genType> 
+	template <typename genType>
 	genType refract(
-		genType const & I, 
-		genType const & N, 
+		genType const & I,
+		genType const & N,
 		typename genType::value_type const & eta);
 
 	/// @}

+ 58 - 67
glm/core/func_geometric.inl

@@ -41,39 +41,30 @@ namespace glm
 		return sqrt(sqr);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tvec2<T>::value_type length
-	(
-		detail::tvec2<T> const & v
-	)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T length(detail::tvec2<T, P> const & v)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'length' only accept floating-point inputs");
 
-		typename detail::tvec2<T>::value_type sqr = v.x * v.x + v.y * v.y;
+		typename detail::tvec2<T, P>::value_type sqr = v.x * v.x + v.y * v.y;
 		return sqrt(sqr);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tvec3<T>::value_type length
-	(
-		detail::tvec3<T> const & v
-	)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T length(detail::tvec3<T, P> const & v)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'length' only accept floating-point inputs");
 
-		typename detail::tvec3<T>::value_type sqr = v.x * v.x + v.y * v.y + v.z * v.z;
+		typename detail::tvec3<T, P>::value_type sqr = v.x * v.x + v.y * v.y + v.z * v.z;
 		return sqrt(sqr);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tvec4<T>::value_type length
-	(
-		detail::tvec4<T> const & v
-	)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T length(detail::tvec4<T, P> const & v)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'length' only accept floating-point inputs");
 
-		typename detail::tvec4<T>::value_type sqr = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
+		typename detail::tvec4<T, P>::value_type sqr = v.x * v.x + v.y * v.y + v.z * v.z + v.w * v.w;
 		return sqrt(sqr);
 	}
 
@@ -81,7 +72,7 @@ namespace glm
 	template <typename genType>
 	GLM_FUNC_QUALIFIER genType distance
 	(
-		genType const & p0, 
+		genType const & p0,
 		genType const & p1
 	)
 	{
@@ -89,12 +80,12 @@ namespace glm
 
 		return length(p1 - p0);
 	}
- 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tvec2<T>::value_type distance
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tvec2<T, P>::value_type distance
 	(
-		detail::tvec2<T> const & p0,
-		detail::tvec2<T> const & p1
+		detail::tvec2<T, P> const & p0,
+		detail::tvec2<T, P> const & p1
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'distance' only accept floating-point inputs");
@@ -102,11 +93,11 @@ namespace glm
 		return length(p1 - p0);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tvec3<T>::value_type distance
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tvec3<T, P>::value_type distance
 	(
-		detail::tvec3<T> const & p0,
-		detail::tvec3<T> const & p1
+		detail::tvec3<T, P> const & p0,
+		detail::tvec3<T, P> const & p1
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'distance' only accept floating-point inputs");
@@ -114,11 +105,11 @@ namespace glm
 		return length(p1 - p0);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tvec4<T>::value_type distance
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tvec4<T, P>::value_type distance
 	(
-		detail::tvec4<T> const & p0,
-		detail::tvec4<T> const & p1
+		detail::tvec4<T, P> const & p0,
+		detail::tvec4<T, P> const & p1
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'distance' only accept floating-point inputs");
@@ -130,7 +121,7 @@ namespace glm
 	template <typename genType>
 	GLM_FUNC_QUALIFIER genType dot
 	(
-		genType const & x, 
+		genType const & x,
 		genType const & y
 	)
 	{
@@ -139,11 +130,11 @@ namespace glm
 		return x * y;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tvec2<T>::value_type dot
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tvec2<T, P>::value_type dot
 	(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & y
+		detail::tvec2<T, P> const & x,
+		detail::tvec2<T, P> const & y
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'dot' only accept floating-point inputs");
@@ -151,11 +142,11 @@ namespace glm
 		return x.x * y.x + x.y * y.y;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T dot
 	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'dot' only accept floating-point inputs");
@@ -179,11 +170,11 @@ namespace glm
 		return Result;
 	}
 */
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T dot
 	(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & y
+		detail::tvec4<T, P> const & x,
+		detail::tvec4<T, P> const & y
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'dot' only accept floating-point inputs");
@@ -192,16 +183,16 @@ namespace glm
 	}
 
 	// cross
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> cross
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> cross
 	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'cross' only accept floating-point inputs");
 
-		return detail::tvec3<T>(
+		return detail::tvec3<T, P>(
 			x.y * y.z - y.y * x.z,
 			x.z * y.x - y.z * x.x,
 			x.x * y.y - y.x * x.y);
@@ -220,39 +211,39 @@ namespace glm
 	}
 
 	// According to issue 10 GLSL 1.10 specification, if length(x) == 0 then result is undefine and generate an error
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> normalize
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> normalize
 	(
-		detail::tvec2<T> const & x
+		detail::tvec2<T, P> const & x
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'normalize' only accept floating-point inputs");
 		
-		typename detail::tvec2<T>::value_type sqr = x.x * x.x + x.y * x.y;
+		typename detail::tvec2<T, P>::value_type sqr = x.x * x.x + x.y * x.y;
 		return x * inversesqrt(sqr);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> normalize
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> normalize
 	(
-		detail::tvec3<T> const & x
+		detail::tvec3<T, P> const & x
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'normalize' only accept floating-point inputs");
 
-		typename detail::tvec3<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z;
+		typename detail::tvec3<T, P>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z;
 		return x * inversesqrt(sqr);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> normalize
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> normalize
 	(
-		detail::tvec4<T> const & x
+		detail::tvec4<T, P> const & x
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'normalize' only accept floating-point inputs");
 		
-		typename detail::tvec4<T>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
+		typename detail::tvec4<T, P>::value_type sqr = x.x * x.x + x.y * x.y + x.z * x.z + x.w * x.w;
 		return x * inversesqrt(sqr);
 	}
 
@@ -260,8 +251,8 @@ namespace glm
 	template <typename genType>
 	GLM_FUNC_QUALIFIER genType faceforward
 	(
-		genType const & N, 
-		genType const & I, 
+		genType const & N,
+		genType const & I,
 		genType const & Nref
 	)
 	{
@@ -272,7 +263,7 @@ namespace glm
 	template <typename genType>
 	GLM_FUNC_QUALIFIER genType reflect
 	(
-		genType const & I, 
+		genType const & I,
 		genType const & N
 	)
 	{
@@ -283,8 +274,8 @@ namespace glm
 	template <typename genType>
 	GLM_FUNC_QUALIFIER genType refract
 	(
-		genType const & I, 
-		genType const & N, 
+		genType const & I,
+		genType const & N,
 		genType const & eta
 	)
 	{
@@ -302,8 +293,8 @@ namespace glm
 	template <typename genType>
 	GLM_FUNC_QUALIFIER genType refract
 	(
-		genType const & I, 
-		genType const & N, 
+		genType const & I,
+		genType const & N,
 		typename genType::value_type const & eta
 	)
 	{

+ 163 - 163
glm/core/func_integer.inl

@@ -37,8 +37,8 @@ namespace glm
 	template <typename genUType>
 	GLM_FUNC_QUALIFIER genUType uaddCarry
 	(
-		genUType const & x, 
-		genUType const & y, 
+		genUType const & x,
+		genUType const & y,
 		genUType & Carry
 	)
 	{
@@ -48,42 +48,42 @@ namespace glm
 		return Result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> uaddCarry
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> uaddCarry
 	(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & y, 
-		detail::tvec2<T> & Carry
+		detail::tvec2<T, P> const & x,
+		detail::tvec2<T, P> const & y,
+		detail::tvec2<T, P> & Carry
 	)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			uaddCarry(x[0], y[0], Carry[0]),
 			uaddCarry(x[1], y[1], Carry[1]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> uaddCarry
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> uaddCarry
 	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y, 
-		detail::tvec3<T> & Carry
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
+		detail::tvec3<T, P> & Carry
 	)
 	{
-		return detail::tvec3<T>(
+		return detail::tvec3<T, P>(
 			uaddCarry(x[0], y[0], Carry[0]),
 			uaddCarry(x[1], y[1], Carry[1]),
 			uaddCarry(x[2], y[2], Carry[2]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> uaddCarry
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> uaddCarry
 	(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & y, 
-		detail::tvec4<T> & Carry
+		detail::tvec4<T, P> const & x,
+		detail::tvec4<T, P> const & y,
+		detail::tvec4<T, P> & Carry
 	)
 	{
-		return detail::tvec4<T>(
+		return detail::tvec4<T, P>(
 			uaddCarry(x[0], y[0], Carry[0]),
 			uaddCarry(x[1], y[1], Carry[1]),
 			uaddCarry(x[2], y[2], Carry[2]),
@@ -94,8 +94,8 @@ namespace glm
 	template <typename genUType>
 	GLM_FUNC_QUALIFIER genUType usubBorrow
 	(
-		genUType const & x, 
-		genUType const & y, 
+		genUType const & x,
+		genUType const & y,
 		genUType & Borrow
 	)
 	{
@@ -106,42 +106,42 @@ namespace glm
 			return genUType((detail::highp_int_t(1) << detail::highp_int_t(32)) + detail::highp_int_t(x) - detail::highp_int_t(y));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> usubBorrow
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> usubBorrow
 	(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & y, 
-		detail::tvec2<T> & Borrow
+		detail::tvec2<T, P> const & x,
+		detail::tvec2<T, P> const & y,
+		detail::tvec2<T, P> & Borrow
 	)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			usubBorrow(x[0], y[0], Borrow[0]),
 			usubBorrow(x[1], y[1], Borrow[1]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> usubBorrow
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> usubBorrow
 	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y, 
-		detail::tvec3<T> & Borrow
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
+		detail::tvec3<T, P> & Borrow
 	)
 	{
-		return detail::tvec3<T>(
+		return detail::tvec3<T, P>(
 			usubBorrow(x[0], y[0], Borrow[0]),
 			usubBorrow(x[1], y[1], Borrow[1]),
 			usubBorrow(x[2], y[2], Borrow[2]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> usubBorrow
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> usubBorrow
 	(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & y, 
-		detail::tvec4<T> & Borrow
+		detail::tvec4<T, P> const & x,
+		detail::tvec4<T, P> const & y,
+		detail::tvec4<T, P> & Borrow
 	)
 	{
-		return detail::tvec4<T>(
+		return detail::tvec4<T, P>(
 			usubBorrow(x[0], y[0], Borrow[0]),
 			usubBorrow(x[1], y[1], Borrow[1]),
 			usubBorrow(x[2], y[2], Borrow[2]),
@@ -152,9 +152,9 @@ namespace glm
 	template <typename genUType>
 	GLM_FUNC_QUALIFIER void umulExtended
 	(
-		genUType const & x, 
-		genUType const & y, 
-		genUType & msb, 
+		genUType const & x,
+		genUType const & y,
+		genUType & msb,
 		genUType & lsb
 	)
 	{
@@ -165,45 +165,45 @@ namespace glm
 		lsb = *(genUType*)&genUType(Value64 >> detail::highp_uint_t(32));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> umulExtended
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> umulExtended
 	(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & y, 
-		detail::tvec2<T> & msb, 
-		detail::tvec2<T> & lsb
+		detail::tvec2<T, P> const & x,
+		detail::tvec2<T, P> const & y,
+		detail::tvec2<T, P> & msb,
+		detail::tvec2<T, P> & lsb
 	)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			umulExtended(x[0], y[0], msb, lsb),
 			umulExtended(x[1], y[1], msb, lsb));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> umulExtended
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> umulExtended
 	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y, 
-		detail::tvec3<T> & msb, 
-		detail::tvec3<T> & lsb
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
+		detail::tvec3<T, P> & msb,
+		detail::tvec3<T, P> & lsb
 	)
 	{
-		return detail::tvec3<T>(
+		return detail::tvec3<T, P>(
 			umulExtended(x[0], y[0], msb, lsb),
 			umulExtended(x[1], y[1], msb, lsb),
 			umulExtended(x[2], y[2], msb, lsb));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> umulExtended
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> umulExtended
 	(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & y, 
-		detail::tvec4<T> & msb, 
-		detail::tvec4<T> & lsb
+		detail::tvec4<T, P> const & x,
+		detail::tvec4<T, P> const & y,
+		detail::tvec4<T, P> & msb,
+		detail::tvec4<T, P> & lsb
 	)
 	{
-		return detail::tvec4<T>(
+		return detail::tvec4<T, P>(
 			umulExtended(x[0], y[0], msb, lsb),
 			umulExtended(x[1], y[1], msb, lsb),
 			umulExtended(x[2], y[2], msb, lsb),
@@ -214,9 +214,9 @@ namespace glm
 	template <typename genIType>
 	GLM_FUNC_QUALIFIER void imulExtended
 	(
-		genIType const & x, 
-		genIType const & y, 
-		genIType & msb, 
+		genIType const & x,
+		genIType const & y,
+		genIType & msb,
 		genIType & lsb
 	)
 	{
@@ -227,45 +227,45 @@ namespace glm
 		lsb = *(genIType*)&genIType(Value64 >> detail::highp_uint_t(32));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> imulExtended
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> imulExtended
 	(
-		detail::tvec2<T> const & x, 
-		detail::tvec2<T> const & y, 
-		detail::tvec2<T> & msb, 
-		detail::tvec2<T> & lsb
+		detail::tvec2<T, P> const & x,
+		detail::tvec2<T, P> const & y,
+		detail::tvec2<T, P> & msb,
+		detail::tvec2<T, P> & lsb
 	)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			imulExtended(x[0], y[0], msb, lsb),
 			imulExtended(x[1], y[1], msb, lsb));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> imulExtended
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> imulExtended
 	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y, 
-		detail::tvec3<T> & msb, 
-		detail::tvec3<T> & lsb
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
+		detail::tvec3<T, P> & msb,
+		detail::tvec3<T, P> & lsb
 	)
 	{
-		return detail::tvec3<T>(
+		return detail::tvec3<T, P>(
 			imulExtended(x[0], y[0], msb, lsb),
 			imulExtended(x[1], y[1], msb, lsb),
 			imulExtended(x[2], y[2], msb, lsb));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> imulExtended
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> imulExtended
 	(
-		detail::tvec4<T> const & x, 
-		detail::tvec4<T> const & y, 
-		detail::tvec4<T> & msb, 
-		detail::tvec4<T> & lsb
+		detail::tvec4<T, P> const & x,
+		detail::tvec4<T, P> const & y,
+		detail::tvec4<T, P> & msb,
+		detail::tvec4<T, P> & lsb
 	)
 	{
-		return detail::tvec4<T>(
+		return detail::tvec4<T, P>(
 			imulExtended(x[0], y[0], msb, lsb),
 			imulExtended(x[1], y[1], msb, lsb),
 			imulExtended(x[2], y[2], msb, lsb),
@@ -276,8 +276,8 @@ namespace glm
 	template <typename genIUType>
 	GLM_FUNC_QUALIFIER genIUType bitfieldExtract
 	(
-		genIUType const & Value, 
-		int const & Offset, 
+		genIUType const & Value,
+		int const & Offset,
 		int const & Bits
 	)
 	{
@@ -291,42 +291,42 @@ namespace glm
 		return ShiftBack;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> bitfieldExtract
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitfieldExtract
 	(
-		detail::tvec2<T> const & Value, 
-		int const & Offset, 
+		detail::tvec2<T, P> const & Value,
+		int const & Offset,
 		int const & Bits
 	)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			bitfieldExtract(Value[0], Offset, Bits),
 			bitfieldExtract(Value[1], Offset, Bits));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> bitfieldExtract
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitfieldExtract
 	(
-		detail::tvec3<T> const & Value, 
-		int const & Offset, 
+		detail::tvec3<T, P> const & Value,
+		int const & Offset,
 		int const & Bits
 	)
 	{
-		return detail::tvec3<T>(
+		return detail::tvec3<T, P>(
 			bitfieldExtract(Value[0], Offset, Bits),
 			bitfieldExtract(Value[1], Offset, Bits),
 			bitfieldExtract(Value[2], Offset, Bits));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> bitfieldExtract
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitfieldExtract
 	(
-		detail::tvec4<T> const & Value, 
-		int const & Offset, 
+		detail::tvec4<T, P> const & Value,
+		int const & Offset,
 		int const & Bits
 	)
 	{
-		return detail::tvec4<T>(
+		return detail::tvec4<T, P>(
 			bitfieldExtract(Value[0], Offset, Bits),
 			bitfieldExtract(Value[1], Offset, Bits),
 			bitfieldExtract(Value[2], Offset, Bits),
@@ -337,9 +337,9 @@ namespace glm
 	template <typename genIUType>
 	GLM_FUNC_QUALIFIER genIUType bitfieldInsert
 	(
-		genIUType const & Base, 
-		genIUType const & Insert, 
-		int const & Offset, 
+		genIUType const & Base,
+		genIUType const & Insert,
+		int const & Offset,
 		int const & Bits
 	)
 	{
@@ -356,45 +356,45 @@ namespace glm
 		return (Base & ~Mask) | (Insert & Mask);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> bitfieldInsert
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitfieldInsert
 	(
-		detail::tvec2<T> const & Base, 
-		detail::tvec2<T> const & Insert, 
-		int const & Offset, 
+		detail::tvec2<T, P> const & Base,
+		detail::tvec2<T, P> const & Insert,
+		int const & Offset,
 		int const & Bits
 	)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			bitfieldInsert(Base[0], Insert[0], Offset, Bits),
 			bitfieldInsert(Base[1], Insert[1], Offset, Bits));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> bitfieldInsert
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitfieldInsert
 	(
-		detail::tvec3<T> const & Base, 
-		detail::tvec3<T> const & Insert, 
-		int const & Offset, 
+		detail::tvec3<T, P> const & Base,
+		detail::tvec3<T, P> const & Insert,
+		int const & Offset,
 		int const & Bits
 	)
 	{
-		return detail::tvec3<T>(
+		return detail::tvec3<T, P>(
 			bitfieldInsert(Base[0], Insert[0], Offset, Bits),
 			bitfieldInsert(Base[1], Insert[1], Offset, Bits),
 			bitfieldInsert(Base[2], Insert[2], Offset, Bits));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> bitfieldInsert
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitfieldInsert
 	(
-		detail::tvec4<T> const & Base, 
-		detail::tvec4<T> const & Insert, 
-		int const & Offset, 
+		detail::tvec4<T, P> const & Base,
+		detail::tvec4<T, P> const & Insert,
+		int const & Offset,
 		int const & Bits
 	)
 	{
-		return detail::tvec4<T>(
+		return detail::tvec4<T, P>(
 			bitfieldInsert(Base[0], Insert[0], Offset, Bits),
 			bitfieldInsert(Base[1], Insert[1], Offset, Bits),
 			bitfieldInsert(Base[2], Insert[2], Offset, Bits),
@@ -432,36 +432,36 @@ namespace glm
 		return Count;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<int> bitCount
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<int, P> bitCount
 	(
-		detail::tvec2<T> const & value
+		detail::tvec2<T, P> const & value
 	)
 	{
-		return detail::tvec2<int>(
+		return detail::tvec2<int, P>(
 			bitCount(value[0]),
 			bitCount(value[1]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<int> bitCount
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<int, P> bitCount
 	(
-		detail::tvec3<T> const & value
+		detail::tvec3<T, P> const & value
 	)
 	{
-		return detail::tvec3<int>(
+		return detail::tvec3<int, P>(
 			bitCount(value[0]),
 			bitCount(value[1]),
 			bitCount(value[2]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<int> bitCount
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<int, P> bitCount
 	(
-		detail::tvec4<T> const & value
+		detail::tvec4<T, P> const & value
 	)
 	{
-		return detail::tvec4<int>(
+		return detail::tvec4<int, P>(
 			bitCount(value[0]),
 			bitCount(value[1]),
 			bitCount(value[2]),
@@ -484,36 +484,36 @@ namespace glm
 		return Bit;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<int> findLSB
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<int, P> findLSB
 	(
-		detail::tvec2<T> const & value
+		detail::tvec2<T, P> const & value
 	)
 	{
-		return detail::tvec2<int>(
+		return detail::tvec2<int, P>(
 			findLSB(value[0]),
 			findLSB(value[1]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<int> findLSB
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<int, P> findLSB
 	(
-		detail::tvec3<T> const & value
+		detail::tvec3<T, P> const & value
 	)
 	{
-		return detail::tvec3<int>(
+		return detail::tvec3<int, P>(
 			findLSB(value[0]),
 			findLSB(value[1]),
 			findLSB(value[2]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<int> findLSB
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<int, P> findLSB
 	(
-		detail::tvec4<T> const & value
+		detail::tvec4<T, P> const & value
 	)
 	{
-		return detail::tvec4<int>(
+		return detail::tvec4<int, P>(
 			findLSB(value[0]),
 			findLSB(value[1]),
 			findLSB(value[2]),
@@ -535,7 +535,7 @@ namespace glm
 			return -1;
 
 		unsigned long Result(0);
-		_BitScanReverse(&Result, Value); 
+		_BitScanReverse(&Result, Value);
 		return int(Result);
 	}
 
@@ -608,36 +608,36 @@ namespace glm
 	}
 //#endif//(GLM_COMPILER)
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<int> findMSB
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<int, P> findMSB
 	(
-		detail::tvec2<T> const & value
+		detail::tvec2<T, P> const & value
 	)
 	{
-		return detail::tvec2<int>(
+		return detail::tvec2<int, P>(
 			findMSB(value[0]),
 			findMSB(value[1]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<int> findMSB
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<int, P> findMSB
 	(
-		detail::tvec3<T> const & value
+		detail::tvec3<T, P> const & value
 	)
 	{
-		return detail::tvec3<int>(
+		return detail::tvec3<int, P>(
 			findMSB(value[0]),
 			findMSB(value[1]),
 			findMSB(value[2]));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<int> findMSB
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<int, P> findMSB
 	(
-		detail::tvec4<T> const & value
+		detail::tvec4<T, P> const & value
 	)
 	{
-		return detail::tvec4<int>(
+		return detail::tvec4<int, P>(
 			findMSB(value[0]),
 			findMSB(value[1]),
 			findMSB(value[2]),

+ 27 - 27
glm/core/func_matrix.hpp

@@ -57,7 +57,7 @@ namespace glm
 		matType const & x, 
 		matType const & y);
 
-	/// Treats the first parameter c as a column vector 
+	/// Treats the first parameter c as a column vector
 	/// and the second parameter r as a row vector
 	/// and does a linear algebraic matrix multiply c * r.
 	/// 
@@ -67,7 +67,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a>
 	/// 
 	/// @todo Clarify the declaration to specify that matType doesn't have to be provided when used.
-	template <typename vecType, typename matType> 
+	template <typename vecType, typename matType>
 	matType outerProduct(
 		vecType const & c, 
 		vecType const & r);
@@ -78,69 +78,69 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/transpose.xml">GLSL transpose man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a>	
-	template <typename matType> 
+	template <typename matType>
 	typename matType::transpose_type transpose(
 		matType const & x);
 	
-	/// Return the determinant of a mat2 matrix. 
+	/// Return the determinant of a mat2 matrix.
 	/// 
 	/// @tparam valType Floating-point scalar types.
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a>	
-	template <typename valType> 
-	typename detail::tmat2x2<valType>::value_type determinant(
-		detail::tmat2x2<valType> const & m);
+	template <typename T, precision P>
+	typename detail::tmat2x2<T, P>::value_type determinant(
+		detail::tmat2x2<T, P> const & m);
 
-	/// Return the determinant of a mat3 matrix. 
+	/// Return the determinant of a mat3 matrix.
 	/// 
 	/// @tparam valType Floating-point scalar types.
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a>	
-	template <typename valType> 
-	typename detail::tmat3x3<valType>::value_type determinant(
-		detail::tmat3x3<valType> const & m);
+	template <typename T, precision P>
+	typename detail::tmat3x3<T, P>::value_type determinant(
+		detail::tmat3x3<T, P> const & m);
 
-	/// Return the determinant of a mat4 matrix. 
+	/// Return the determinant of a mat4 matrix.
 	/// 
 	/// @tparam valType Floating-point scalar types.
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/determinant.xml">GLSL determinant man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a>		
-	template <typename valType> 
-	typename detail::tmat4x4<valType>::value_type determinant(
-		detail::tmat4x4<valType> const & m);
+	template <typename T, precision P>
+	typename detail::tmat4x4<T, P>::value_type determinant(
+		detail::tmat4x4<T, P> const & m);
 
-	/// Return the inverse of a mat2 matrix. 
+	/// Return the inverse of a mat2 matrix.
 	/// 
 	/// @tparam valType Floating-point scalar types.
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a>	 
-	template <typename valType> 
-	detail::tmat2x2<valType> inverse(
-		detail::tmat2x2<valType> const & m);
+	template <typename T, precision P>
+	detail::tmat2x2<T, P> inverse(
+		detail::tmat2x2<T, P> const & m);
 
-	/// Return the inverse of a mat3 matrix. 
+	/// Return the inverse of a mat3 matrix.
 	/// 
 	/// @tparam valType Floating-point scalar types.
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a> 
-	template <typename valType> 
-	detail::tmat3x3<valType> inverse(
-		detail::tmat3x3<valType> const & m);
+	template <typename T, precision P>
+	detail::tmat3x3<T, P> inverse(
+		detail::tmat3x3<T, P> const & m);
 
-	/// Return the inverse of a mat4 matrix. 
+	/// Return the inverse of a mat4 matrix.
 	/// 
 	/// @tparam valType Floating-point scalar types.
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/inverse.xml">GLSL inverse man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.6 Matrix Functions</a>
-	template <typename valType> 
-	detail::tmat4x4<valType> inverse(
-		detail::tmat4x4<valType> const & m);
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> inverse(
+		detail::tmat4x4<T, P> const & m);
 
 	/// @}
 }//namespace glm

+ 124 - 124
glm/core/func_matrix.inl

@@ -32,7 +32,7 @@ namespace glm
 	template <typename matType>
 	GLM_FUNC_QUALIFIER matType matrixCompMult
 	(
-		matType const & x, 
+		matType const & x,
 		matType const & y
 	)
 	{
@@ -45,16 +45,16 @@ namespace glm
 	}
 
 	// outerProduct
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x2<T> outerProduct
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, P> outerProduct
 	(
-		detail::tvec2<T> const & c, 
-		detail::tvec2<T> const & r
+		detail::tvec2<T, P> const & c,
+		detail::tvec2<T, P> const & r
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
 
-		detail::tmat2x2<T> m(detail::tmat2x2<T>::null);
+		detail::tmat2x2<T, P> m(detail::tmat2x2<T, P>::null);
 		m[0][0] = c[0] * r[0];
 		m[0][1] = c[1] * r[0];
 		m[1][0] = c[0] * r[1];
@@ -62,46 +62,46 @@ namespace glm
 		return m;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> outerProduct
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> outerProduct
 	(
-		detail::tvec3<T> const & c, 
-		detail::tvec3<T> const & r
+		detail::tvec3<T, P> const & c,
+		detail::tvec3<T, P> const & r
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
 
-		detail::tmat3x3<T> m(detail::tmat3x3<T>::null);
-		for(typename detail::tmat3x3<T>::size_type i(0); i < m.length(); ++i)
+		detail::tmat3x3<T, P> m(detail::tmat3x3<T, P>::null);
+		for(typename detail::tmat3x3<T, P>::size_type i(0); i < m.length(); ++i)
 			m[i] = c * r[i];
 		return m;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> outerProduct
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> outerProduct
 	(
-		detail::tvec4<T> const & c, 
-		detail::tvec4<T> const & r
+		detail::tvec4<T, P> const & c,
+		detail::tvec4<T, P> const & r
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
 
-		detail::tmat4x4<T> m(detail::tmat4x4<T>::null);
-		for(typename detail::tmat4x4<T>::size_type i(0); i < m.length(); ++i)
+		detail::tmat4x4<T, P> m(detail::tmat4x4<T, P>::null);
+		for(typename detail::tmat4x4<T, P>::size_type i(0); i < m.length(); ++i)
 			m[i] = c * r[i];
 		return m;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x3<T> outerProduct
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat2x3<T, P> outerProduct
 	(
-		detail::tvec3<T> const & c, 
-		detail::tvec2<T> const & r
+		detail::tvec3<T, P> const & c,
+		detail::tvec2<T, P> const & r
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
 
-		detail::tmat2x3<T> m(detail::tmat2x3<T>::null);
+		detail::tmat2x3<T, P> m(detail::tmat2x3<T, P>::null);
 		m[0][0] = c.x * r.x;
 		m[0][1] = c.y * r.x;
 		m[0][2] = c.z * r.x;
@@ -111,16 +111,16 @@ namespace glm
 		return m;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x2<T> outerProduct
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x2<T, P> outerProduct
 	(
-		detail::tvec2<T> const & c, 
-		detail::tvec3<T> const & r
+		detail::tvec2<T, P> const & c,
+		detail::tvec3<T, P> const & r
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
 
-		detail::tmat3x2<T> m(detail::tmat3x2<T>::null);
+		detail::tmat3x2<T, P> m(detail::tmat3x2<T, P>::null);
 		m[0][0] = c.x * r.x;
 		m[0][1] = c.y * r.x;
 		m[1][0] = c.x * r.y;
@@ -130,16 +130,16 @@ namespace glm
 		return m;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x4<T> outerProduct
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat2x4<T, P> outerProduct
 	(
-		detail::tvec4<T> const & c, 
-		detail::tvec2<T> const & r
+		detail::tvec4<T, P> const & c,
+		detail::tvec2<T, P> const & r
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
 
-		detail::tmat2x4<T> m(detail::tmat2x4<T>::null);
+		detail::tmat2x4<T, P> m(detail::tmat2x4<T, P>::null);
 		m[0][0] = c.x * r.x;
 		m[0][1] = c.y * r.x;
 		m[0][2] = c.z * r.x;
@@ -151,16 +151,16 @@ namespace glm
 		return m;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x2<T> outerProduct
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x2<T, P> outerProduct
 	(
-		detail::tvec2<T> const & c, 
-		detail::tvec4<T> const & r
+		detail::tvec2<T, P> const & c, 
+		detail::tvec4<T, P> const & r
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
 
-		detail::tmat4x2<T> m(detail::tmat4x2<T>::null);
+		detail::tmat4x2<T, P> m(detail::tmat4x2<T, P>::null);
 		m[0][0] = c.x * r.x;
 		m[0][1] = c.y * r.x;
 		m[1][0] = c.x * r.y;
@@ -172,16 +172,16 @@ namespace glm
 		return m;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x4<T> outerProduct
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x4<T, P> outerProduct
 	(
-		detail::tvec4<T> const & c, 
-		detail::tvec3<T> const & r
+		detail::tvec4<T, P> const & c, 
+		detail::tvec3<T, P> const & r
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
 
-		detail::tmat3x4<T> m(detail::tmat3x4<T>::null);
+		detail::tmat3x4<T, P> m(detail::tmat3x4<T, P>::null);
 		m[0][0] = c.x * r.x;
 		m[0][1] = c.y * r.x;
 		m[0][2] = c.z * r.x;
@@ -197,16 +197,16 @@ namespace glm
 		return m;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x3<T> outerProduct
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x3<T, P> outerProduct
 	(
-		detail::tvec3<T> const & c, 
-		detail::tvec4<T> const & r
+		detail::tvec3<T, P> const & c,
+		detail::tvec4<T, P> const & r
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'outerProduct' only accept floating-point inputs");
 
-		detail::tmat4x3<T> m(detail::tmat4x3<T>::null);
+		detail::tmat4x3<T, P> m(detail::tmat4x3<T, P>::null);
 		m[0][0] = c.x * r.x;
 		m[0][1] = c.y * r.x;
 		m[0][2] = c.z * r.x;
@@ -222,15 +222,15 @@ namespace glm
 		return m;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x2<T> transpose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, P> transpose
 	(
-		detail::tmat2x2<T> const & m
+		detail::tmat2x2<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
 
-		detail::tmat2x2<T> result(detail::tmat2x2<T>::null);
+		detail::tmat2x2<T, P> result(detail::tmat2x2<T, P>::null);
 		result[0][0] = m[0][0];
 		result[0][1] = m[1][0];
 		result[1][0] = m[0][1];
@@ -238,15 +238,15 @@ namespace glm
 		return result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> transpose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> transpose
 	(
-		detail::tmat3x3<T> const & m
+		detail::tmat3x3<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
 
-		detail::tmat3x3<T> result(detail::tmat3x3<T>::null);
+		detail::tmat3x3<T, P> result(detail::tmat3x3<T, P>::null);
 		result[0][0] = m[0][0];
 		result[0][1] = m[1][0];
 		result[0][2] = m[2][0];
@@ -261,15 +261,15 @@ namespace glm
 		return result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> transpose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> transpose
 	(
-		detail::tmat4x4<T> const & m
+		detail::tmat4x4<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
 
-		detail::tmat4x4<T> result(detail::tmat4x4<T>::null);
+		detail::tmat4x4<T, P> result(detail::tmat4x4<T, P>::null);
 		result[0][0] = m[0][0];
 		result[0][1] = m[1][0];
 		result[0][2] = m[2][0];
@@ -292,15 +292,15 @@ namespace glm
 		return result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x3<T> transpose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat2x3<T, P> transpose
 	(
-		detail::tmat3x2<T> const & m
+		detail::tmat3x2<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
 
-		detail::tmat2x3<T> result(detail::tmat2x3<T>::null);
+		detail::tmat2x3<T, P> result(detail::tmat2x3<T, P>::null);
 		result[0][0] = m[0][0];
 		result[0][1] = m[1][0];
 		result[0][2] = m[2][0];
@@ -310,15 +310,15 @@ namespace glm
 		return result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x2<T> transpose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x2<T, P> transpose
 	(
-		detail::tmat2x3<T> const & m
+		detail::tmat2x3<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
 
-		detail::tmat3x2<T> result(detail::tmat3x2<T>::null);
+		detail::tmat3x2<T, P> result(detail::tmat3x2<T, P>::null);
 		result[0][0] = m[0][0];
 		result[0][1] = m[1][0];
 		result[1][0] = m[0][1];
@@ -328,15 +328,15 @@ namespace glm
 		return result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x4<T> transpose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat2x4<T, P> transpose
 	(
-		detail::tmat4x2<T> const & m
+		detail::tmat4x2<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
 
-		detail::tmat2x4<T> result(detail::tmat2x4<T>::null);
+		detail::tmat2x4<T, P> result(detail::tmat2x4<T, P>::null);
 		result[0][0] = m[0][0];
 		result[0][1] = m[1][0];
 		result[0][2] = m[2][0];
@@ -348,15 +348,15 @@ namespace glm
 		return result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x2<T> transpose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x2<T, P> transpose
 	(
-		detail::tmat2x4<T> const & m
+		detail::tmat2x4<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
 
-		detail::tmat4x2<T> result(detail::tmat4x2<T>::null);
+		detail::tmat4x2<T, P> result(detail::tmat4x2<T, P>::null);
 		result[0][0] = m[0][0];
 		result[0][1] = m[1][0];
 		result[1][0] = m[0][1];
@@ -368,15 +368,15 @@ namespace glm
 		return result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x4<T> transpose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x4<T, P> transpose
 	(
-		detail::tmat4x3<T> const & m
+		detail::tmat4x3<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
 
-		detail::tmat3x4<T> result(detail::tmat3x4<T>::null);
+		detail::tmat3x4<T, P> result(detail::tmat3x4<T, P>::null);
 		result[0][0] = m[0][0];
 		result[0][1] = m[1][0];
 		result[0][2] = m[2][0];
@@ -392,15 +392,15 @@ namespace glm
 		return result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x3<T> transpose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x3<T, P> transpose
 	(
-		detail::tmat3x4<T> const & m
+		detail::tmat3x4<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'transpose' only accept floating-point inputs");
 
-		detail::tmat4x3<T> result(detail::tmat4x3<T>::null);
+		detail::tmat4x3<T, P> result(detail::tmat4x3<T, P>::null);
 		result[0][0] = m[0][0];
 		result[0][1] = m[1][0];
 		result[0][2] = m[2][0];
@@ -416,10 +416,10 @@ namespace glm
 		return result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tmat2x2<T>::value_type determinant
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tmat2x2<T, P>::value_type determinant
 	(
-		detail::tmat2x2<T> const & m
+		detail::tmat2x2<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'determinant' only accept floating-point inputs");
@@ -427,10 +427,10 @@ namespace glm
 		return m[0][0] * m[1][1] - m[1][0] * m[0][1];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tmat3x3<T>::value_type determinant
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tmat3x3<T, P>::value_type determinant
 	(
-		detail::tmat3x3<T> const & m
+		detail::tmat3x3<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'determinant' only accept floating-point inputs");
@@ -441,10 +441,10 @@ namespace glm
 			+ m[2][0] * (m[0][1] * m[1][2] - m[1][1] * m[0][2]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename detail::tmat4x4<T>::value_type determinant
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename detail::tmat4x4<T, P>::value_type determinant
 	(
-		detail::tmat4x4<T> const & m
+		detail::tmat4x4<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'determinant' only accept floating-point inputs");
@@ -456,7 +456,7 @@ namespace glm
 		T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
 		T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
 
-		detail::tvec4<T> DetCof(
+		detail::tvec4<T, P> DetCof(
 			+ (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
 			- (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
 			+ (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
@@ -468,10 +468,10 @@ namespace glm
 				+ m[0][3] * DetCof[3];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat2x2<T> inverse
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, P> inverse
 	(
-		detail::tmat2x2<T> const & m
+		detail::tmat2x2<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'inverse' only accept floating-point inputs");
@@ -479,19 +479,19 @@ namespace glm
 		//valType Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1];
 		T Determinant = determinant(m);
 
-		detail::tmat2x2<T> Inverse(
+		detail::tmat2x2<T, P> Inverse(
 			+ m[1][1] / Determinant,
-			- m[0][1] / Determinant, 
+			- m[0][1] / Determinant,
 			- m[1][0] / Determinant,
 			+ m[0][0] / Determinant);
 
 		return Inverse;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> inverse
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> inverse
 	(
-		detail::tmat3x3<T> const & m
+		detail::tmat3x3<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'inverse' only accept floating-point inputs");
@@ -502,7 +502,7 @@ namespace glm
 
 		T Determinant = determinant(m);
 
-		detail::tmat3x3<T> Inverse(detail::tmat3x3<T>::null);
+		detail::tmat3x3<T, P> Inverse(detail::tmat3x3<T, P>::null);
 		Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
 		Inverse[1][0] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);
 		Inverse[2][0] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
@@ -517,10 +517,10 @@ namespace glm
 		return Inverse;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> inverse
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> inverse
 	(
-		detail::tmat4x4<T> const & m
+		detail::tmat4x4<T, P> const & m
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<T>::is_float, "'inverse' only accept floating-point inputs");
@@ -549,29 +549,29 @@ namespace glm
 		T Coef22 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
 		T Coef23 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
 
-		detail::tvec4<T> const SignA(+1, -1, +1, -1);
-		detail::tvec4<T> const SignB(-1, +1, -1, +1);
+		detail::tvec4<T, P> const SignA(+1, -1, +1, -1);
+		detail::tvec4<T, P> const SignB(-1, +1, -1, +1);
 
-		detail::tvec4<T> Fac0(Coef00, Coef00, Coef02, Coef03);
-		detail::tvec4<T> Fac1(Coef04, Coef04, Coef06, Coef07);
-		detail::tvec4<T> Fac2(Coef08, Coef08, Coef10, Coef11);
-		detail::tvec4<T> Fac3(Coef12, Coef12, Coef14, Coef15);
-		detail::tvec4<T> Fac4(Coef16, Coef16, Coef18, Coef19);
-		detail::tvec4<T> Fac5(Coef20, Coef20, Coef22, Coef23);
+		detail::tvec4<T, P> Fac0(Coef00, Coef00, Coef02, Coef03);
+		detail::tvec4<T, P> Fac1(Coef04, Coef04, Coef06, Coef07);
+		detail::tvec4<T, P> Fac2(Coef08, Coef08, Coef10, Coef11);
+		detail::tvec4<T, P> Fac3(Coef12, Coef12, Coef14, Coef15);
+		detail::tvec4<T, P> Fac4(Coef16, Coef16, Coef18, Coef19);
+		detail::tvec4<T, P> Fac5(Coef20, Coef20, Coef22, Coef23);
 
-		detail::tvec4<T> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]);
-		detail::tvec4<T> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]);
-		detail::tvec4<T> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]);
-		detail::tvec4<T> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]);
+		detail::tvec4<T, P> Vec0(m[1][0], m[0][0], m[0][0], m[0][0]);
+		detail::tvec4<T, P> Vec1(m[1][1], m[0][1], m[0][1], m[0][1]);
+		detail::tvec4<T, P> Vec2(m[1][2], m[0][2], m[0][2], m[0][2]);
+		detail::tvec4<T, P> Vec3(m[1][3], m[0][3], m[0][3], m[0][3]);
 
-		detail::tvec4<T> Inv0 = SignA * (Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2);
-		detail::tvec4<T> Inv1 = SignB * (Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4);
-		detail::tvec4<T> Inv2 = SignA * (Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5);
-		detail::tvec4<T> Inv3 = SignB * (Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5);
+		detail::tvec4<T, P> Inv0 = SignA * (Vec1 * Fac0 - Vec2 * Fac1 + Vec3 * Fac2);
+		detail::tvec4<T, P> Inv1 = SignB * (Vec0 * Fac0 - Vec2 * Fac3 + Vec3 * Fac4);
+		detail::tvec4<T, P> Inv2 = SignA * (Vec0 * Fac1 - Vec1 * Fac3 + Vec3 * Fac5);
+		detail::tvec4<T, P> Inv3 = SignB * (Vec0 * Fac2 - Vec1 * Fac4 + Vec2 * Fac5);
 
-		detail::tmat4x4<T> Inverse(Inv0, Inv1, Inv2, Inv3);
+		detail::tmat4x4<T, P> Inverse(Inv0, Inv1, Inv2, Inv3);
 
-		detail::tvec4<T> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]);
+		detail::tvec4<T, P> Row0(Inverse[0][0], Inverse[1][0], Inverse[2][0], Inverse[3][0]);
 
 		T Determinant = glm::dot(m[0], Row0);
 

+ 3 - 3
glm/core/func_noise.hpp

@@ -59,7 +59,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise2.xml">GLSL noise2 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13 Noise Functions</a>
 	template <typename genType>
-	detail::tvec2<typename genType::value_type> noise2(genType const & x);
+	detail::tvec2<typename genType::value_type, defaultp> noise2(genType const & x);
 
 	/// Returns a 3D noise value based on the input value x.
 	///
@@ -68,7 +68,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise3.xml">GLSL noise3 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13 Noise Functions</a>
 	template <typename genType>
-	detail::tvec3<typename genType::value_type> noise3(genType const & x);
+	detail::tvec3<typename genType::value_type, defaultp> noise3(genType const & x);
 
 	/// Returns a 4D noise value based on the input value x.
 	///
@@ -77,7 +77,7 @@ namespace glm
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/noise4.xml">GLSL noise4 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.13 Noise Functions</a>
 	template <typename genType>
-	detail::tvec4<typename genType::value_type> noise4(genType const & x);
+	detail::tvec4<typename genType::value_type, defaultp> noise4(genType const & x);
 
 	/// @}
 }//namespace glm

+ 175 - 170
glm/core/func_noise.inl

@@ -31,86 +31,87 @@ namespace glm
 	template <typename T>
 	GLM_FUNC_QUALIFIER T noise1(T const & x)
 	{
-		return noise1(glm::detail::tvec2<T>(x, T(0)));
+		return noise1(detail::tvec2<T, defaultp>(x, T(0)));
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec2<T> noise2(T const & x)
+	GLM_FUNC_QUALIFIER detail::tvec2<T, defaultp> noise2(T const & x)
 	{
-		return glm::detail::tvec2<T>(
+		return detail::tvec2<T, defaultp>(
 			noise1(x + T(0.0)),
 			noise1(x + T(1.0)));
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec3<T> noise3(T const & x)
+	GLM_FUNC_QUALIFIER detail::tvec3<T, defaultp> noise3(T const & x)
 	{
-		return glm::detail::tvec3<T>(
+		return detail::tvec3<T, defaultp>(
 			noise1(x - T(1.0)),
 			noise1(x + T(0.0)),
 			noise1(x + T(1.0)));
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec4<T> noise4(T const & x)
+	GLM_FUNC_QUALIFIER detail::tvec4<T, defaultp> noise4(T const & x)
 	{
-		return glm::detail::tvec4<T>(
+		return detail::tvec4<T, defaultp>(
 			noise1(x - T(1.0)),
 			noise1(x + T(0.0)),
 			noise1(x + T(1.0)),
 			noise1(x + T(2.0)));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER T noise1(glm::detail::tvec2<T> const & v)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T noise1(detail::tvec2<T, P> const & v)
 	{
-		detail::tvec4<T> const C = detail::tvec4<T>(
-													T( 0.211324865405187),  // (3.0 -  sqrt(3.0)) / 6.0
-													T( 0.366025403784439),  //  0.5 * (sqrt(3.0)  - 1.0)
-													T(-0.577350269189626),	// -1.0 + 2.0 * C.x
-													T( 0.024390243902439)); //  1.0 / 41.0
+		detail::tvec4<T, P> const C = detail::tvec4<T, P>(
+			T( 0.211324865405187),		// (3.0 -  sqrt(3.0)) / 6.0
+			T( 0.366025403784439),		//  0.5 * (sqrt(3.0)  - 1.0)
+			T(-0.577350269189626),		// -1.0 + 2.0 * C.x
+			T( 0.024390243902439));		//  1.0 / 41.0
 		
 		// First corner
-		detail::tvec2<T> i  = floor(v + dot(v, detail::tvec2<T>(C[1])));
-		detail::tvec2<T> x0 = v -   i + dot(i, detail::tvec2<T>(C[0]));
+		detail::tvec2<T, P> i  = floor(v + dot(v, detail::tvec2<T, P>(C[1])));
+		detail::tvec2<T, P> x0 = v -   i + dot(i, detail::tvec2<T, P>(C[0]));
 		
 		// Other corners
 		//i1.x = step( x0.y, x0.x ); // x0.x > x0.y ? 1.0 : 0.0
 		//i1.y = 1.0 - i1.x;
-		detail::tvec2<T> i1 = (x0.x > x0.y) ? detail::tvec2<T>(1, 0) : detail::tvec2<T>(0, 1);
+		detail::tvec2<T, P> i1 = (x0.x > x0.y) ? detail::tvec2<T, P>(1, 0) : detail::tvec2<T, P>(0, 1);
+
 		// x0 = x0 - 0.0 + 0.0 * C.xx ;
 		// x1 = x0 - i1 + 1.0 * C.xx ;
 		// x2 = x0 - 1.0 + 2.0 * C.xx ;
-		detail::tvec4<T> x12 = detail::tvec4<T>(x0.x, x0.y, x0.x, x0.y) + detail::tvec4<T>(C.x, C.x, C.z, C.z);
-		x12 = detail::tvec4<T>(detail::tvec2<T>(x12) - i1, x12.z, x12.w);
+		detail::tvec4<T, P> x12 = detail::tvec4<T, P>(x0.x, x0.y, x0.x, x0.y) + detail::tvec4<T, P>(C.x, C.x, C.z, C.z);
+		x12 = detail::tvec4<T, P>(detail::tvec2<T, P>(x12) - i1, x12.z, x12.w);
 		
 		// Permutations
 		i = mod(i, T(289)); // Avoid truncation effects in permutation
-		detail::tvec3<T> p = permute(
-									 permute(i.y + detail::tvec3<T>(T(0), i1.y, T(1)))
-									 + i.x + detail::tvec3<T>(T(0), i1.x, T(1)));
+		detail::tvec3<T, P> p = permute(
+			permute(i.y + detail::tvec3<T, P>(T(0), i1.y, T(1))) + i.x + detail::tvec3<T, P>(T(0), i1.x, T(1)));
+		
+		detail::tvec3<T, P> m = max(T(0.5) - detail::tvec3<T, P>(
+			dot(x0, x0),
+			dot(detail::tvec2<T, P>(x12.x, x12.y), detail::tvec2<T, P>(x12.x, x12.y)),
+			dot(detail::tvec2<T, P>(x12.z, x12.w), detail::tvec2<T, P>(x12.z, x12.w))), T(0));
 		
-		detail::tvec3<T> m = max(T(0.5) - detail::tvec3<T>(
-														   dot(x0, x0), 
-														   dot(detail::tvec2<T>(x12.x, x12.y), detail::tvec2<T>(x12.x, x12.y)), 
-														   dot(detail::tvec2<T>(x12.z, x12.w), detail::tvec2<T>(x12.z, x12.w))), T(0));
-		m = m * m ;
-		m = m * m ;
+		m = m * m;
+		m = m * m;
 		
 		// Gradients: 41 points uniformly over a line, mapped onto a diamond.
 		// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
 		
-		detail::tvec3<T> x = T(2) * fract(p * C.w) - T(1);
-		detail::tvec3<T> h = abs(x) - T(0.5);
-		detail::tvec3<T> ox = floor(x + T(0.5));
-		detail::tvec3<T> a0 = x - ox;
+		detail::tvec3<T, P> x = T(2) * fract(p * C.w) - T(1);
+		detail::tvec3<T, P> h = abs(x) - T(0.5);
+		detail::tvec3<T, P> ox = floor(x + T(0.5));
+		detail::tvec3<T, P> a0 = x - ox;
 		
 		// Normalise gradients implicitly by scaling m
 		// Inlined for speed: m *= taylorInvSqrt( a0*a0 + h*h );
 		m *= T(1.79284291400159) - T(0.85373472095314) * (a0 * a0 + h * h);
 		
 		// Compute final noise value at P
-		detail::tvec3<T> g;
+		detail::tvec3<T, P> g;
 		g.x  = a0.x  * x0.x  + h.x  * x0.y;
 		//g.yz = a0.yz * x12.xz + h.yz * x12.yw;
 		g.y = a0.y * x12.x + h.y * x12.y;
@@ -118,151 +119,154 @@ namespace glm
 		return T(130) * dot(m, g);
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER T noise1(detail::tvec3<T> const & v)
-	{ 
-		detail::tvec2<T> const C(1.0 / 6.0, 1.0 / 3.0);
-		detail::tvec4<T> const D(0.0, 0.5, 1.0, 2.0);
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T noise1(detail::tvec3<T, P> const & v)
+	{
+		detail::tvec2<T, P> const C(1.0 / 6.0, 1.0 / 3.0);
+		detail::tvec4<T, P> const D(0.0, 0.5, 1.0, 2.0);
 		
 		// First corner
-		detail::tvec3<T> i(floor(v + dot(v, detail::tvec3<T>(C.y))));
-		detail::tvec3<T> x0(v - i + dot(i, detail::tvec3<T>(C.x)));
+		detail::tvec3<T, P> i(floor(v + dot(v, detail::tvec3<T, P>(C.y))));
+		detail::tvec3<T, P> x0(v - i + dot(i, detail::tvec3<T, P>(C.x)));
 		
 		// Other corners
-		detail::tvec3<T> g(step(detail::tvec3<T>(x0.y, x0.z, x0.x), x0));
-		detail::tvec3<T> l(T(1) - g);
-		detail::tvec3<T> i1(min(g, detail::tvec3<T>(l.z, l.x, l.y)));
-		detail::tvec3<T> i2(max(g, detail::tvec3<T>(l.z, l.x, l.y)));
-		
-		//   x0 = x0 - 0.0 + 0.0 * C.xxx;
-		//   x1 = x0 - i1  + 1.0 * C.xxx;
-		//   x2 = x0 - i2  + 2.0 * C.xxx;
-		//   x3 = x0 - 1.0 + 3.0 * C.xxx;
-		detail::tvec3<T> x1(x0 - i1 + C.x);
-		detail::tvec3<T> x2(x0 - i2 + C.y); // 2.0*C.x = 1/3 = C.y
-		detail::tvec3<T> x3(x0 - D.y);      // -1.0+3.0*C.x = -0.5 = -D.y
+		detail::tvec3<T, P> g(step(detail::tvec3<T, P>(x0.y, x0.z, x0.x), x0));
+		detail::tvec3<T, P> l(T(1) - g);
+		detail::tvec3<T, P> i1(min(g, detail::tvec3<T, P>(l.z, l.x, l.y)));
+		detail::tvec3<T, P> i2(max(g, detail::tvec3<T, P>(l.z, l.x, l.y)));
+		
+		// x0 = x0 - 0.0 + 0.0 * C.xxx;
+		// x1 = x0 - i1  + 1.0 * C.xxx;
+		// x2 = x0 - i2  + 2.0 * C.xxx;
+		// x3 = x0 - 1.0 + 3.0 * C.xxx;
+		detail::tvec3<T, P> x1(x0 - i1 + C.x);
+		detail::tvec3<T, P> x2(x0 - i2 + C.y);		// 2.0*C.x = 1/3 = C.y
+		detail::tvec3<T, P> x3(x0 - D.y);			// -1.0+3.0*C.x = -0.5 = -D.y
 		
 		// Permutations
 		i = mod289(i); 
-		detail::tvec4<T> p(permute(permute(permute( 
-												   i.z + detail::tvec4<T>(T(0), i1.z, i2.z, T(1))) + 
-										   i.y + detail::tvec4<T>(T(0), i1.y, i2.y, T(1))) + 
-								   i.x + detail::tvec4<T>(T(0), i1.x, i2.x, T(1))));
+		detail::tvec4<T, P> p(permute(permute(permute(
+			i.z + detail::tvec4<T, P>(T(0), i1.z, i2.z, T(1))) +
+			i.y + detail::tvec4<T, P>(T(0), i1.y, i2.y, T(1))) +
+			i.x + detail::tvec4<T, P>(T(0), i1.x, i2.x, T(1))));
 		
 		// Gradients: 7x7 points over a square, mapped onto an octahedron.
 		// The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294)
 		T n_ = T(0.142857142857); // 1.0/7.0
-		detail::tvec3<T> ns(n_ * detail::tvec3<T>(D.w, D.y, D.z) - detail::tvec3<T>(D.x, D.z, D.x));
+		detail::tvec3<T, P> ns(n_ * detail::tvec3<T, P>(D.w, D.y, D.z) - detail::tvec3<T, P>(D.x, D.z, D.x));
 		
-		detail::tvec4<T> j(p - T(49) * floor(p * ns.z * ns.z));  //  mod(p,7*7)
+		detail::tvec4<T, P> j(p - T(49) * floor(p * ns.z * ns.z));	// mod(p,7*7)
 		
-		detail::tvec4<T> x_(floor(j * ns.z));
-		detail::tvec4<T> y_(floor(j - T(7) * x_));    // mod(j,N)
+		detail::tvec4<T, P> x_(floor(j * ns.z));
+		detail::tvec4<T, P> y_(floor(j - T(7) * x_));				// mod(j,N)
 		
-		detail::tvec4<T> x(x_ * ns.x + ns.y);
-		detail::tvec4<T> y(y_ * ns.x + ns.y);
-		detail::tvec4<T> h(T(1) - abs(x) - abs(y));
+		detail::tvec4<T, P> x(x_ * ns.x + ns.y);
+		detail::tvec4<T, P> y(y_ * ns.x + ns.y);
+		detail::tvec4<T, P> h(T(1) - abs(x) - abs(y));
 		
-		detail::tvec4<T> b0(x.x, x.y, y.x, y.y);
-		detail::tvec4<T> b1(x.z, x.w, y.z, y.w);
+		detail::tvec4<T, P> b0(x.x, x.y, y.x, y.y);
+		detail::tvec4<T, P> b1(x.z, x.w, y.z, y.w);
 		
 		// vec4 s0 = vec4(lessThan(b0,0.0))*2.0 - 1.0;
 		// vec4 s1 = vec4(lessThan(b1,0.0))*2.0 - 1.0;
-		detail::tvec4<T> s0(floor(b0) * T(2) + T(1));
-		detail::tvec4<T> s1(floor(b1) * T(2) + T(1));
-		detail::tvec4<T> sh(-step(h, detail::tvec4<T>(0.0)));
+		detail::tvec4<T, P> s0(floor(b0) * T(2) + T(1));
+		detail::tvec4<T, P> s1(floor(b1) * T(2) + T(1));
+		detail::tvec4<T, P> sh(-step(h, detail::tvec4<T, P>(0.0)));
 		
-		detail::tvec4<T> a0 = detail::tvec4<T>(b0.x, b0.z, b0.y, b0.w) + detail::tvec4<T>(s0.x, s0.z, s0.y, s0.w) * detail::tvec4<T>(sh.x, sh.x, sh.y, sh.y);
-		detail::tvec4<T> a1 = detail::tvec4<T>(b1.x, b1.z, b1.y, b1.w) + detail::tvec4<T>(s1.x, s1.z, s1.y, s1.w) * detail::tvec4<T>(sh.z, sh.z, sh.w, sh.w);
+		detail::tvec4<T, P> a0 = detail::tvec4<T, P>(b0.x, b0.z, b0.y, b0.w) + detail::tvec4<T, P>(s0.x, s0.z, s0.y, s0.w) * detail::tvec4<T, P>(sh.x, sh.x, sh.y, sh.y);
+		detail::tvec4<T, P> a1 = detail::tvec4<T, P>(b1.x, b1.z, b1.y, b1.w) + detail::tvec4<T, P>(s1.x, s1.z, s1.y, s1.w) * detail::tvec4<T, P>(sh.z, sh.z, sh.w, sh.w);
 		
-		detail::tvec3<T> p0(a0.x, a0.y, h.x);
-		detail::tvec3<T> p1(a0.z, a0.w, h.y);
-		detail::tvec3<T> p2(a1.x, a1.y, h.z);
-		detail::tvec3<T> p3(a1.z, a1.w, h.w);
+		detail::tvec3<T, P> p0(a0.x, a0.y, h.x);
+		detail::tvec3<T, P> p1(a0.z, a0.w, h.y);
+		detail::tvec3<T, P> p2(a1.x, a1.y, h.z);
+		detail::tvec3<T, P> p3(a1.z, a1.w, h.w);
 		
 		// Normalise gradients
-		detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
+		detail::tvec4<T, P> norm = taylorInvSqrt(detail::tvec4<T, P>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
 		p0 *= norm.x;
 		p1 *= norm.y;
 		p2 *= norm.z;
 		p3 *= norm.w;
 		
 		// Mix final noise value
-		detail::tvec4<T> m = max(T(0.6) - detail::tvec4<T>(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), T(0));
+		detail::tvec4<T, P> m = max(T(0.6) - detail::tvec4<T, P>(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), T(0));
 		m = m * m;
-		return T(42) * dot(m * m, detail::tvec4<T>(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
+		return T(42) * dot(m * m, detail::tvec4<T, P>(dot(p0, x0), dot(p1, x1), dot(p2, x2), dot(p3, x3)));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER T noise1(detail::tvec4<T> const & v)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T noise1(detail::tvec4<T, P> const & v)
 	{
-		detail::tvec4<T> const C(
-								 0.138196601125011,  // (5 - sqrt(5))/20  G4
-								 0.276393202250021,  // 2 * G4
-								 0.414589803375032,  // 3 * G4
-								 -0.447213595499958); // -1 + 4 * G4
+		detail::tvec4<T, P> const C(
+			0.138196601125011,		// (5 - sqrt(5))/20  G4
+			0.276393202250021,		// 2 * G4
+			0.414589803375032,		// 3 * G4
+			-0.447213595499958);	// -1 + 4 * G4
 		
 		// (sqrt(5) - 1)/4 = F4, used once below
 		T const F4 = T(0.309016994374947451);
 		
 		// First corner
-		detail::tvec4<T> i  = floor(v + dot(v, vec4(F4)));
-		detail::tvec4<T> x0 = v -   i + dot(i, vec4(C.x));
+		detail::tvec4<T, P> i  = floor(v + dot(v, detail::tvec4<T, P>(F4)));
+		detail::tvec4<T, P> x0 = v -   i + dot(i, detail::tvec4<T, P>(C.x));
 		
 		// Other corners
 		
 		// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
-		detail::tvec4<T> i0;
-		detail::tvec3<T> isX = step(detail::tvec3<T>(x0.y, x0.z, x0.w), detail::tvec3<T>(x0.x));
-		detail::tvec3<T> isYZ = step(detail::tvec3<T>(x0.z, x0.w, x0.w), detail::tvec3<T>(x0.y, x0.y, x0.z));
+		detail::tvec4<T, P> i0;
+		detail::tvec3<T, P> isX = step(detail::tvec3<T, P>(x0.y, x0.z, x0.w), detail::tvec3<T, P>(x0.x));
+		detail::tvec3<T, P> isYZ = step(detail::tvec3<T, P>(x0.z, x0.w, x0.w), detail::tvec3<T, P>(x0.y, x0.y, x0.z));
+		
 		//  i0.x = dot(isX, vec3(1.0));
 		//i0.x = isX.x + isX.y + isX.z;
 		//i0.yzw = T(1) - isX;
-		i0 = detail::tvec4<T>(isX.x + isX.y + isX.z, T(1) - isX);
+		i0 = detail::tvec4<T, P>(isX.x + isX.y + isX.z, T(1) - isX);
+		
 		//  i0.y += dot(isYZ.xy, vec2(1.0));
 		i0.y += isYZ.x + isYZ.y;
-		//i0.zw += 1.0 - detail::tvec2<T>(isYZ.x, isYZ.y);
+		
+		//i0.zw += 1.0 - detail::tvec2<T, P>(isYZ.x, isYZ.y);
 		i0.z += T(1) - isYZ.x;
 		i0.w += T(1) - isYZ.y;
 		i0.z += isYZ.z;
 		i0.w += T(1) - isYZ.z;
 		
 		// i0 now contains the unique values 0,1,2,3 in each channel
-		detail::tvec4<T> i3 = clamp(i0, 0.0, 1.0);
-		detail::tvec4<T> i2 = clamp(i0 - 1.0, 0.0, 1.0);
-		detail::tvec4<T> i1 = clamp(i0 - 2.0, 0.0, 1.0);
+		detail::tvec4<T, P> i3 = clamp(i0, T(0), T(1));
+		detail::tvec4<T, P> i2 = clamp(i0 - T(1), T(0), T(1));
+		detail::tvec4<T, P> i1 = clamp(i0 - T(2), T(0), T(1));
 		
 		//  x0 = x0 - 0.0 + 0.0 * C.xxxx
 		//  x1 = x0 - i1  + 0.0 * C.xxxx
 		//  x2 = x0 - i2  + 0.0 * C.xxxx
 		//  x3 = x0 - i3  + 0.0 * C.xxxx
 		//  x4 = x0 - 1.0 + 4.0 * C.xxxx
-		detail::tvec4<T> x1 = x0 - i1 + C.x;
-		detail::tvec4<T> x2 = x0 - i2 + C.y;
-		detail::tvec4<T> x3 = x0 - i3 + C.z;
-		detail::tvec4<T> x4 = x0 + C.w;
+		detail::tvec4<T, P> x1 = x0 - i1 + C.x;
+		detail::tvec4<T, P> x2 = x0 - i2 + C.y;
+		detail::tvec4<T, P> x3 = x0 - i3 + C.z;
+		detail::tvec4<T, P> x4 = x0 + C.w;
 		
 		// Permutations
-		i = mod(i, T(289)); 
+		i = mod(i, T(289));
 		T j0 = permute(permute(permute(permute(i.w) + i.z) + i.y) + i.x);
-		detail::tvec4<T> j1 = permute(permute(permute(permute(
-															  i.w + detail::tvec4<T>(i1.w, i2.w, i3.w, T(1)))
-													  + i.z + detail::tvec4<T>(i1.z, i2.z, i3.z, T(1)))
-											  + i.y + detail::tvec4<T>(i1.y, i2.y, i3.y, T(1)))
-									  + i.x + detail::tvec4<T>(i1.x, i2.x, i3.x, T(1)));
+		detail::tvec4<T, P> j1 = permute(permute(permute(permute(
+			i.w + detail::tvec4<T, P>(i1.w, i2.w, i3.w, T(1))) +
+			i.z + detail::tvec4<T, P>(i1.z, i2.z, i3.z, T(1))) +
+			i.y + detail::tvec4<T, P>(i1.y, i2.y, i3.y, T(1))) +
+			i.x + detail::tvec4<T, P>(i1.x, i2.x, i3.x, T(1)));
 		
 		// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
 		// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
-		detail::tvec4<T> ip = detail::tvec4<T>(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0));
+		detail::tvec4<T, P> ip = detail::tvec4<T, P>(T(1) / T(294), T(1) / T(49), T(1) / T(7), T(0));
 		
-		detail::tvec4<T> p0 = grad4(j0,   ip);
-		detail::tvec4<T> p1 = grad4(j1.x, ip);
-		detail::tvec4<T> p2 = grad4(j1.y, ip);
-		detail::tvec4<T> p3 = grad4(j1.z, ip);
-		detail::tvec4<T> p4 = grad4(j1.w, ip);
+		detail::tvec4<T, P> p0 = grad4(j0,   ip);
+		detail::tvec4<T, P> p1 = grad4(j1.x, ip);
+		detail::tvec4<T, P> p2 = grad4(j1.y, ip);
+		detail::tvec4<T, P> p3 = grad4(j1.z, ip);
+		detail::tvec4<T, P> p4 = grad4(j1.w, ip);
 		
 		// Normalise gradients
-		detail::tvec4<T> norm = taylorInvSqrt(detail::tvec4<T>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
+		detail::tvec4<T, P> norm = taylorInvSqrt(detail::tvec4<T, P>(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
 		p0 *= norm.x;
 		p1 *= norm.y;
 		p2 *= norm.z;
@@ -270,95 +274,96 @@ namespace glm
 		p4 *= taylorInvSqrt(dot(p4, p4));
 		
 		// Mix contributions from the five corners
-		detail::tvec3<T> m0 = max(T(0.6) - detail::tvec3<T>(dot(x0, x0), dot(x1, x1), dot(x2, x2)), T(0));
-		detail::tvec2<T> m1 = max(T(0.6) - detail::tvec2<T>(dot(x3, x3), dot(x4, x4)             ), T(0));
+		detail::tvec3<T, P> m0 = max(T(0.6) - detail::tvec3<T, P>(dot(x0, x0), dot(x1, x1), dot(x2, x2)), T(0));
+		detail::tvec2<T, P> m1 = max(T(0.6) - detail::tvec2<T, P>(dot(x3, x3), dot(x4, x4)             ), T(0));
 		m0 = m0 * m0;
 		m1 = m1 * m1;
-		return T(49) * 
-		(dot(m0 * m0, detail::tvec3<T>(dot(p0, x0), dot(p1, x1), dot(p2, x2))) + 
-		 dot(m1 * m1, detail::tvec2<T>(dot(p3, x3), dot(p4, x4))));
+		
+		return T(49) * (
+			dot(m0 * m0, detail::tvec3<T, P>(dot(p0, x0), dot(p1, x1), dot(p2, x2))) +
+			dot(m1 * m1, detail::tvec2<T, P>(dot(p3, x3), dot(p4, x4))));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec2<T> noise2(glm::detail::tvec2<T> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> noise2(detail::tvec2<T, P> const & x)
 	{
-		return glm::detail::tvec2<T>(
-			noise1(x + glm::detail::tvec2<T>(0.0)),
-			noise1(glm::detail::tvec2<T>(0.0) - x));
+		return detail::tvec2<T, P>(
+			noise1(x + detail::tvec2<T, P>(0.0)),
+			noise1(detail::tvec2<T, P>(0.0) - x));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec2<T> noise2(glm::detail::tvec3<T> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> noise2(detail::tvec3<T, P> const & x)
 	{
-		return glm::detail::tvec2<T>(
-			noise1(x + glm::detail::tvec3<T>(0.0)),
-			noise1(glm::detail::tvec3<T>(0.0) - x));
+		return detail::tvec2<T, P>(
+			noise1(x + detail::tvec3<T, P>(0.0)),
+			noise1(detail::tvec3<T, P>(0.0) - x));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec2<T> noise2(glm::detail::tvec4<T> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> noise2(detail::tvec4<T, P> const & x)
 	{
-		return glm::detail::tvec2<T>(
-			noise1(x + glm::detail::tvec4<T>(0.0)),
-			noise1(glm::detail::tvec4<T>(0.0) - x));
+		return detail::tvec2<T, P>(
+			noise1(x + detail::tvec4<T, P>(0)),
+			noise1(detail::tvec4<T, P>(0) - x));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec3<T> noise3(glm::detail::tvec2<T> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> noise3(detail::tvec2<T, P> const & x)
 	{
-		return glm::detail::tvec3<T>(
-			noise1(x - glm::detail::tvec2<T>(1.0)),
-			noise1(x + glm::detail::tvec2<T>(0.0)),
-			noise1(x + glm::detail::tvec2<T>(1.0)));
+		return detail::tvec3<T, P>(
+			noise1(x - detail::tvec2<T, P>(1.0)),
+			noise1(x + detail::tvec2<T, P>(0.0)),
+			noise1(x + detail::tvec2<T, P>(1.0)));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec3<T> noise3(glm::detail::tvec3<T> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> noise3(detail::tvec3<T, P> const & x)
 	{
-		return glm::detail::tvec3<T>(
-			noise1(x - glm::detail::tvec3<T>(1.0)),
-			noise1(x + glm::detail::tvec3<T>(0.0)),
-			noise1(x + glm::detail::tvec3<T>(1.0)));
+		return detail::tvec3<T, P>(
+			noise1(x - detail::tvec3<T, P>(1.0)),
+			noise1(x + detail::tvec3<T, P>(0.0)),
+			noise1(x + detail::tvec3<T, P>(1.0)));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec3<T> noise3(glm::detail::tvec4<T> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> noise3(detail::tvec4<T, P> const & x)
 	{
-		return glm::detail::tvec3<T>(
-			noise1(x - glm::detail::tvec4<T>(1.0)),
-			noise1(x + glm::detail::tvec4<T>(0.0)),
-			noise1(x + glm::detail::tvec4<T>(1.0)));
+		return detail::tvec3<T, P>(
+			noise1(x - detail::tvec4<T, P>(1)),
+			noise1(x + detail::tvec4<T, P>(0)),
+			noise1(x + detail::tvec4<T, P>(1)));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec4<T> noise4(glm::detail::tvec2<T> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> noise4(detail::tvec2<T, P> const & x)
 	{
-		return glm::detail::tvec4<T>(
-			noise1(x - glm::detail::tvec2<T>(1.0)),
-			noise1(x + glm::detail::tvec2<T>(0.0)),
-			noise1(x + glm::detail::tvec2<T>(1.0)),
-			noise1(x + glm::detail::tvec2<T>(2.0)));
+		return detail::tvec4<T, P>(
+			noise1(x - detail::tvec2<T, P>(1)),
+			noise1(x + detail::tvec2<T, P>(0)),
+			noise1(x + detail::tvec2<T, P>(1)),
+			noise1(x + detail::tvec2<T, P>(2)));
 	}
 
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec4<T> noise4(glm::detail::tvec3<T> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> noise4(detail::tvec3<T, P> const & x)
 	{
-		return glm::detail::tvec4<T>(
-			noise1(x - glm::detail::tvec3<T>(1.0)),
-			noise1(x + glm::detail::tvec3<T>(0.0)),
-			noise1(x + glm::detail::tvec3<T>(1.0)),
-			noise1(x + glm::detail::tvec3<T>(2.0)));
+		return detail::tvec4<T, P>(
+			noise1(x - detail::tvec3<T, P>(1)),
+			noise1(x + detail::tvec3<T, P>(0)),
+			noise1(x + detail::tvec3<T, P>(1)),
+			noise1(x + detail::tvec3<T, P>(2)));
 	}
 	
-	template <typename T>
-	GLM_FUNC_QUALIFIER glm::detail::tvec4<T> noise4(glm::detail::tvec4<T> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> noise4(detail::tvec4<T, P> const & x)
 	{
-		return glm::detail::tvec4<T>(
-			noise1(x - glm::detail::tvec4<T>(1.0)),
-			noise1(x + glm::detail::tvec4<T>(0.0)),
-			noise1(x + glm::detail::tvec4<T>(1.0)),
-			noise1(x + glm::detail::tvec4<T>(2.0)));
+		return detail::tvec4<T, P>(
+			noise1(x - detail::tvec4<T, P>(1)),
+			noise1(x + detail::tvec4<T, P>(0)),
+			noise1(x + detail::tvec4<T, P>(1)),
+			noise1(x + detail::tvec4<T, P>(2)));
 	}
 	
 }//namespace glm

+ 11 - 11
glm/core/func_packing.hpp

@@ -52,7 +52,7 @@ namespace glm
 	//! 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packUnorm2x16.xml">GLSL packUnorm2x16 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	uint32 packUnorm2x16(detail::tvec2<float32> const & v);
+	uint32 packUnorm2x16(detail::tvec2<float32, defaultp> const & v);
 
 	//! First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. 
 	//! Then, the results are packed into the returned 32-bit unsigned integer.
@@ -65,7 +65,7 @@ namespace glm
 	//! 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packSnorm2x16.xml">GLSL packSnorm2x16 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	uint32 packSnorm2x16(detail::tvec2<float32> const & v);
+	uint32 packSnorm2x16(detail::tvec2<float32, defaultp> const & v);
 
 	//! First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. 
 	//! Then, the results are packed into the returned 32-bit unsigned integer.
@@ -78,7 +78,7 @@ namespace glm
 	//! 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packUnorm4x8.xml">GLSL packUnorm4x8 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	uint32 packUnorm4x8(detail::tvec4<float32> const & v);
+	uint32 packUnorm4x8(detail::tvec4<float32, defaultp> const & v);
 
 	//! First, converts each component of the normalized floating-point value v into 8- or 16-bit integer values. 
 	//! Then, the results are packed into the returned 32-bit unsigned integer.
@@ -91,7 +91,7 @@ namespace glm
 	//! 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packSnorm4x8.xml">GLSL packSnorm4x8 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	uint32 packSnorm4x8(detail::tvec4<float32> const & v);
+	uint32 packSnorm4x8(detail::tvec4<float32, defaultp> const & v);
 
 	//! First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. 
 	//! Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector.
@@ -104,7 +104,7 @@ namespace glm
 	//! 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackUnorm2x16.xml">GLSL unpackUnorm2x16 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	detail::tvec2<float32> unpackUnorm2x16(uint32 const & p);
+	detail::tvec2<float32, defaultp> unpackUnorm2x16(uint32 const & p);
 
 	//! First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. 
 	//! Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector.
@@ -117,7 +117,7 @@ namespace glm
 	//! 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackSnorm2x16.xml">GLSL unpackSnorm2x16 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	detail::tvec2<float32> unpackSnorm2x16(uint32 const & p);
+	detail::tvec2<float32, defaultp> unpackSnorm2x16(uint32 const & p);
 
 	/// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. 
 	/// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector.
@@ -130,7 +130,7 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackUnorm4x8.xml">GLSL unpackUnorm4x8 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	detail::tvec4<float32> unpackUnorm4x8(uint32 const & p);
+	detail::tvec4<float32, defaultp> unpackUnorm4x8(uint32 const & p);
 
 	/// First, unpacks a single 32-bit unsigned integer p into a pair of 16-bit unsigned integers, four 8-bit unsigned integers, or four 8-bit signed integers. 
 	/// Then, each component is converted to a normalized floating-point value to generate the returned two- or four-component vector.
@@ -143,7 +143,7 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackSnorm4x8.xml">GLSL unpackSnorm4x8 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	detail::tvec4<float32> unpackSnorm4x8(uint32 const & p);
+	detail::tvec4<float32, defaultp> unpackSnorm4x8(uint32 const & p);
 
 	/// Returns a double-precision value obtained by packing the components of v into a 64-bit value. 
 	/// If an IEEE 754 Inf or NaN is created, it will not signal, and the resulting floating point value is unspecified. 
@@ -153,7 +153,7 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packDouble2x32.xml">GLSL packDouble2x32 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	double packDouble2x32(detail::tvec2<uint32> const & v);
+	double packDouble2x32(detail::tvec2<uint32, defaultp> const & v);
 
 	/// Returns a two-component unsigned integer vector representation of v. 
 	/// The bit-level representation of v is preserved. 
@@ -162,7 +162,7 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/unpackDouble2x32.xml">GLSL unpackDouble2x32 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	detail::tvec2<uint32> unpackDouble2x32(double const & v);
+	detail::tvec2<uint32, defaultp> unpackDouble2x32(double const & v);
 
 	/// Returns an unsigned integer obtained by converting the components of a two-component floating-point vector 
 	/// to the 16-bit floating-point representation found in the OpenGL Specification, 
@@ -172,7 +172,7 @@ namespace glm
 	/// 
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/packHalf2x16.xml">GLSL packHalf2x16 man page</a>
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 8.4 Floating-Point Pack and Unpack Functions</a>
-	uint packHalf2x16(detail::tvec2<float32> const & v);
+	uint packHalf2x16(detail::tvec2<float32, defaultp> const & v);
 	
 	/// Returns a two-component floating-point vector with components obtained by unpacking a 32-bit unsigned integer into a pair of 16-bit values, 
 	/// interpreting those values as 16-bit floating-point numbers according to the OpenGL Specification, 

+ 36 - 36
glm/core/func_packing.inl

@@ -28,24 +28,24 @@
 
 namespace glm
 {
-	GLM_FUNC_QUALIFIER uint32 packUnorm2x16(detail::tvec2<float32> const & v)
+	GLM_FUNC_QUALIFIER uint32 packUnorm2x16(detail::tvec2<float32, defaultp> const & v)
 	{
 		uint16 A(uint16(round(clamp(v.x, 0.0f, 1.0f) * 65535.0f)));
 		uint16 B(uint16(round(clamp(v.y, 0.0f, 1.0f) * 65535.0f)));
 		return uint32((B << 16) | A);
 	}
 
-	GLM_FUNC_QUALIFIER detail::tvec2<float32> unpackUnorm2x16(uint32 const & p)
+	GLM_FUNC_QUALIFIER detail::tvec2<float32, defaultp> unpackUnorm2x16(uint32 const & p)
 	{
 		uint32 Mask16((1 << 16) - 1);
 		uint32 A((p >>  0) & Mask16);
 		uint32 B((p >> 16) & Mask16);
-		return detail::tvec2<float32>(
-			A * 1.0f / 65535.0f, 
+		return detail::tvec2<float32, defaultp>(
+			A * 1.0f / 65535.0f,
 			B * 1.0f / 65535.0f);
 	}
 	
-	GLM_FUNC_QUALIFIER uint32 packSnorm2x16(detail::tvec2<float32> const & v)
+	GLM_FUNC_QUALIFIER uint32 packSnorm2x16(detail::tvec2<float32, defaultp> const & v)
 	{
 		union iu
 		{
@@ -53,14 +53,14 @@ namespace glm
 			uint16 u;
 		} A, B;
 		
-		detail::tvec2<float32> Unpack = clamp(v ,-1.0f, 1.0f) * 32767.0f;
+		detail::tvec2<float32, defaultp> Unpack = clamp(v ,-1.0f, 1.0f) * 32767.0f;
 		A.i = detail::int16(round(Unpack.x));
 		B.i = detail::int16(round(Unpack.y));
 		uint32 Pack = (uint32(B.u) << 16) | (uint32(A.u) << 0);
 		return Pack;
 	}
 
-	GLM_FUNC_QUALIFIER detail::tvec2<float32> unpackSnorm2x16(uint32 const & p)
+	GLM_FUNC_QUALIFIER detail::tvec2<float32, defaultp> unpackSnorm2x16(uint32 const & p)
 	{
 		union iu
 		{
@@ -71,12 +71,12 @@ namespace glm
 		uint32 Mask16((1 << 16) - 1);
 		A.u = uint16((p >>  0) & Mask16);
 		B.u = uint16((p >> 16) & Mask16);
-		detail::tvec2<float32> Pack(A.i, B.i);
+		detail::tvec2<float32, defaultp> Pack(A.i, B.i);
 		
 		return clamp(Pack * 1.0f / 32767.0f, -1.0f, 1.0f);
 	}
 
-	GLM_FUNC_QUALIFIER uint32 packUnorm4x8(detail::tvec4<float32> const & v)
+	GLM_FUNC_QUALIFIER uint32 packUnorm4x8(detail::tvec4<float32, defaultp> const & v)
 	{
 		uint8 A((uint8)round(clamp(v.x, 0.0f, 1.0f) * 255.0f));
 		uint8 B((uint8)round(clamp(v.y, 0.0f, 1.0f) * 255.0f));
@@ -85,21 +85,21 @@ namespace glm
 		return uint32((D << 24) | (C << 16) | (B << 8) | A);
 	}
 
-	GLM_FUNC_QUALIFIER detail::tvec4<float32> unpackUnorm4x8(uint32 const & p)
+	GLM_FUNC_QUALIFIER detail::tvec4<float32, defaultp> unpackUnorm4x8(uint32 const & p)
 	{	
 		uint32 Mask8((1 << 8) - 1);
 		uint32 A((p >>  0) & Mask8);
 		uint32 B((p >>  8) & Mask8);
 		uint32 C((p >> 16) & Mask8);
 		uint32 D((p >> 24) & Mask8);
-		return detail::tvec4<float32>(
+		return detail::tvec4<float32, defaultp>(
 			A * 1.0f / 255.0f, 
 			B * 1.0f / 255.0f, 
 			C * 1.0f / 255.0f, 
 			D * 1.0f / 255.0f);
 	}
 	
-	GLM_FUNC_QUALIFIER uint32 packSnorm4x8(detail::tvec4<float32> const & v)
+	GLM_FUNC_QUALIFIER uint32 packSnorm4x8(detail::tvec4<float32, defaultp> const & v)
 	{
 		union iu
 		{
@@ -107,7 +107,7 @@ namespace glm
 			uint8 u;
 		} A, B, C, D;
 	
-		detail::tvec4<float32> Unpack = clamp(v ,-1.0f, 1.0f) * 127.0f;
+		detail::tvec4<float32, defaultp> Unpack = clamp(v ,-1.0f, 1.0f) * 127.0f;
 		A.i = int8(round(Unpack.x));
 		B.i = int8(round(Unpack.y));
 		C.i = int8(round(Unpack.z));
@@ -116,7 +116,7 @@ namespace glm
 		return Pack;
 	}
 	
-	GLM_FUNC_QUALIFIER detail::tvec4<float32> unpackSnorm4x8(uint32 const & p)
+	GLM_FUNC_QUALIFIER detail::tvec4<float32, defaultp> unpackSnorm4x8(uint32 const & p)
 	{	
 		union iu
 		{
@@ -129,12 +129,12 @@ namespace glm
 		B.u = uint8((p >>  8) & Mask8);
 		C.u = uint8((p >> 16) & Mask8);
 		D.u = uint8((p >> 24) & Mask8);
-		detail::tvec4<float32> Pack(A.i, B.i, C.i, D.i);
+		detail::tvec4<float32, defaultp> Pack(A.i, B.i, C.i, D.i);
 	
 		return clamp(Pack * 1.0f / 127.0f, -1.0f, 1.0f);
 	}
 
-	GLM_FUNC_QUALIFIER double packDouble2x32(detail::tvec2<uint32> const & v)
+	GLM_FUNC_QUALIFIER double packDouble2x32(detail::tvec2<uint32, defaultp> const & v)
 	{
 		struct uint32_pair
 		{
@@ -155,7 +155,7 @@ namespace glm
 		//return *(double*)&v;
 	}
 
-	GLM_FUNC_QUALIFIER detail::tvec2<uint> unpackDouble2x32(double const & v)
+	GLM_FUNC_QUALIFIER detail::tvec2<uint, defaultp> unpackDouble2x32(double const & v)
 	{
 		struct uint32_pair
 		{
@@ -171,35 +171,35 @@ namespace glm
 
 		Helper.input = v;
 
-		return detail::tvec2<uint>(Helper.output.x, Helper.output.y);
+		return detail::tvec2<uint, defaultp>(Helper.output.x, Helper.output.y);
 	}
 
-	GLM_FUNC_QUALIFIER uint packHalf2x16(detail::tvec2<float> const & v)
+	GLM_FUNC_QUALIFIER uint packHalf2x16(detail::tvec2<float, defaultp> const & v)
 	{
 		union helper
-		{ 
-			uint other; 
-			struct 
-			{ 
-				detail::hdata a, b; 
-			} orig; 
-		} Pack; 
-
-		Pack.orig.a = detail::toFloat16(v.x); 
-		Pack.orig.b = detail::toFloat16(v.y); 
+		{
+			uint other;
+			struct
+			{
+				detail::hdata a, b;
+			} orig;
+		} Pack;
+
+		Pack.orig.a = detail::toFloat16(v.x);
+		Pack.orig.b = detail::toFloat16(v.y);
 		return Pack.other;
 	}
 
 	GLM_FUNC_QUALIFIER vec2 unpackHalf2x16(uint const & v)
 	{
 		union helper
-		{ 
-			uint other; 
-			struct 
-			{ 
-				detail::hdata a, b; 
-			} orig; 
-		} Unpack; 
+		{
+			uint other;
+			struct
+			{
+				detail::hdata a, b;
+			} orig;
+		} Unpack;
 		Unpack.other = v;
 
 		return vec2(detail::toFloat32(Unpack.orig.a), detail::toFloat32(Unpack.orig.b));

+ 1 - 1
glm/core/func_vector_relational.hpp

@@ -52,7 +52,7 @@ namespace glm
 	///
 	/// @see <a href="http://www.opengl.org/sdk/docs/manglsl/xhtml/lessThan.xml">GLSL lessThan 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 <typename vecType> 
+	template <typename vecType>
 	typename vecType::bool_type lessThan(vecType const & x, vecType const & y);
 
 	/// Returns the component-wise comparison of result x <= y.

+ 67 - 67
glm/core/func_vector_relational.inl

@@ -28,149 +28,149 @@
 
 namespace glm
 {
-	template <typename T, template <typename> class vecType> 
-	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type lessThan
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER typename vecType<T, P>::bool_type lessThan
 	(
-		vecType<T> const & x, 
-		vecType<T> const & y
+		vecType<T, P> const & x,
+		vecType<T, P> const & y
 	)
 	{
-		GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES, 
-			"Invalid template instantiation of 'lessThan', GLM vector types required");
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'lessThan', GLM vector types required");
 		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
 			"Invalid template instantiation of 'lessThan', GLM vector types required floating-point or integer value types vectors");
 		assert(x.length() == y.length());
 
-		typename vecType<bool>::bool_type Result(vecType<bool>::null);
-		for(typename vecType<bool>::size_type i = 0; i < x.length(); ++i)
+		typename vecType<bool, P>::bool_type Result(vecType<bool, P>::null);
+		for(typename vecType<bool, P>::size_type i = 0; i < x.length(); ++i)
 			Result[i] = x[i] < y[i];
 
 		return Result;
 	}
 
-	template <typename T, template <typename> class vecType> 
-	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type lessThanEqual
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER typename vecType<T, P>::bool_type lessThanEqual
 	(
-		vecType<T> const & x, 
-		vecType<T> const & y
+		vecType<T, P> const & x,
+		vecType<T, P> const & y
 	)
 	{
-		GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES, 
-			"Invalid template instantiation of 'lessThanEqual', GLM vector types required");
-		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO, 
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'lessThanEqual', GLM vector types required");
+		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
 			"Invalid template instantiation of 'lessThanEqual', GLM vector types required floating-point or integer value types vectors");
 		assert(x.length() == y.length());
 
-		typename vecType<bool>::bool_type Result(vecType<bool>::null);
-		for(typename vecType<bool>::size_type i = 0; i < x.length(); ++i)
+		typename vecType<bool, P>::bool_type Result(vecType<bool, P>::null);
+		for(typename vecType<bool, P>::size_type i = 0; i < x.length(); ++i)
 			Result[i] = x[i] <= y[i];
 		return Result;
 	}
 
-	template <typename T, template <typename> class vecType> 
-	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type greaterThan
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER typename vecType<T, P>::bool_type greaterThan
 	(
-		vecType<T> const & x, 
-		vecType<T> const & y
+		vecType<T, P> const & x,
+		vecType<T, P> const & y
 	)
 	{
-		GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES, 
-			"Invalid template instantiation of 'greaterThan', GLM vector types required");
-		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO, 
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'greaterThan', GLM vector types required");
+		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
 			"Invalid template instantiation of 'greaterThan', GLM vector types required floating-point or integer value types vectors");
 		assert(x.length() == y.length());
 
-		typename vecType<bool>::bool_type Result(vecType<bool>::null);
-		for(typename vecType<bool>::size_type i = 0; i < x.length(); ++i)
+		typename vecType<bool, P>::bool_type Result(vecType<bool, P>::null);
+		for(typename vecType<bool, P>::size_type i = 0; i < x.length(); ++i)
 			Result[i] = x[i] > y[i];
 		return Result;
 	}
 
-	template <typename T, template <typename> class vecType> 
-	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type greaterThanEqual
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER typename vecType<T, P>::bool_type greaterThanEqual
 	(
-		vecType<T> const & x, 
-		vecType<T> const & y
+		vecType<T, P> const & x,
+		vecType<T, P> const & y
 	)
 	{
-		GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES, 
-			"Invalid template instantiation of 'greaterThanEqual', GLM vector types required");
-		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO, 
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'greaterThanEqual', GLM vector types required");
+		GLM_STATIC_ASSERT(detail::is_bool<T>::_NO,
 			"Invalid template instantiation of 'greaterThanEqual', GLM vector types required floating-point or integer value types vectors");
 		assert(x.length() == y.length());
 
-		typename vecType<bool>::bool_type Result(vecType<bool>::null);
-		for(typename vecType<bool>::size_type i = 0; i < x.length(); ++i)
+		typename vecType<bool, P>::bool_type Result(vecType<bool, P>::null);
+		for(typename vecType<bool, P>::size_type i = 0; i < x.length(); ++i)
 			Result[i] = x[i] >= y[i];
 		return Result;
 	}
 
-	template <typename T, template <typename> class vecType> 
-	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type equal
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER typename vecType<T, P>::bool_type equal
 	(
-		vecType<T> const & x, 
-		vecType<T> const & y
+		vecType<T, P> const & x,
+		vecType<T, P> const & y
 	)
 	{
-		GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES, 
-			"Invalid template instantiation of 'equal', GLM vector types required");
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'equal', GLM vector types required");
 		assert(x.length() == y.length());
 
-		typename vecType<bool>::bool_type Result(vecType<bool>::null);
-		for(typename vecType<bool>::size_type i = 0; i < x.length(); ++i)
+		typename vecType<bool, P>::bool_type Result(vecType<bool, P>::null);
+		for(typename vecType<bool, P>::size_type i = 0; i < x.length(); ++i)
 			Result[i] = x[i] == y[i];
 		return Result;
 	}
 
-	template <typename T, template <typename> class vecType> 
-	GLM_FUNC_QUALIFIER typename vecType<T>::bool_type notEqual
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER typename vecType<T, P>::bool_type notEqual
 	(
-		vecType<T> const & x, 
-		vecType<T> const & y
+		vecType<T, P> const & x,
+		vecType<T, P> const & y
 	)
 	{
-		GLM_STATIC_ASSERT(detail::is_vector<vecType<T> >::_YES, 
-			"Invalid template instantiation of 'notEqual', GLM vector types required");
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<T, P> >::_YES,
+		//	"Invalid template instantiation of 'notEqual', GLM vector types required");
 		assert(x.length() == y.length());
 
-		typename vecType<bool>::bool_type Result(vecType<bool>::null);
-		for(typename vecType<bool>::size_type i = 0; i < x.length(); ++i)
+		typename vecType<bool, P>::bool_type Result(vecType<bool, P>::null);
+		for(typename vecType<bool, P>::size_type i = 0; i < x.length(); ++i)
 			Result[i] = x[i] != y[i];
 		return Result;
 	}
 
-	template <template <typename> class vecType> 
-	GLM_FUNC_QUALIFIER bool any(vecType<bool> const & v)
+	template <precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER bool any(vecType<bool, P> const & v)
 	{
-		GLM_STATIC_ASSERT(detail::is_vector<vecType<bool> >::_YES, 
-			"Invalid template instantiation of 'any', GLM boolean vector types required");
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<bool, P> >::_YES,
+		//	"Invalid template instantiation of 'any', GLM boolean vector types required");
 
 		bool Result = false;
-		for(typename vecType<bool>::size_type i = 0; i < v.length(); ++i)
+		for(typename vecType<bool, P>::size_type i = 0; i < v.length(); ++i)
 			Result = Result || v[i];
 		return Result;
 	}
 
-	template <template <typename> class vecType> 
-	GLM_FUNC_QUALIFIER bool all(vecType<bool> const & v)
+	template <precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER bool all(vecType<bool, P> const & v)
 	{
-		GLM_STATIC_ASSERT(detail::is_vector<vecType<bool> >::_YES, 
-			"Invalid template instantiation of 'all', GLM boolean vector types required");
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<bool, P> >::_YES,
+		//	"Invalid template instantiation of 'all', GLM boolean vector types required");
 
 		bool Result = true;
-		for(typename vecType<bool>::size_type i = 0; i < v.length(); ++i)
+		for(typename vecType<bool, P>::size_type i = 0; i < v.length(); ++i)
 			Result = Result && v[i];
 		return Result;
 	}
 
-	template <template <typename> class vecType> 
-	GLM_FUNC_QUALIFIER vecType<bool> not_(vecType<bool> const & v)
+	template <precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER vecType<bool, P> not_(vecType<bool, P> const & v)
 	{
-		GLM_STATIC_ASSERT(detail::is_vector<vecType<bool> >::_YES, 
-			"Invalid template instantiation of 'not_', GLM vector types required");
+		//GLM_STATIC_ASSERT(detail::is_vector<vecType<bool, P> >::_YES,
+		//	"Invalid template instantiation of 'not_', GLM vector types required");
 
-		typename vecType<bool>::bool_type Result(vecType<bool>::null);
-		for(typename vecType<bool>::size_type i = 0; i < v.length(); ++i)
+		typename vecType<bool, P>::bool_type Result(vecType<bool, P>::null);
+		for(typename vecType<bool, P>::size_type i = 0; i < v.length(); ++i)
 			Result[i] = !v[i];
 		return Result;
 	}

+ 2 - 2
glm/core/intrinsic_matrix.inl

@@ -448,7 +448,7 @@ GLM_FUNC_QUALIFIER __m128 sse_detd_ps
 	__m128 MulC = _mm_mul_ps(Swp2C, Swp3C);
 	__m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC);
 
-	//detail::tvec4<T> DetCof(
+	//detail::tvec4<T, P> DetCof(
 	//	+ (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
 	//	- (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
 	//	+ (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),
@@ -514,7 +514,7 @@ GLM_FUNC_QUALIFIER __m128 sse_det_ps
 	__m128 MulC = _mm_mul_ps(Swp2C, Swp3C);
 	__m128 SubF = _mm_sub_ps(_mm_movehl_ps(MulC, MulC), MulC);
 
-	//detail::tvec4<T> DetCof(
+	//detail::tvec4<T, P> DetCof(
 	//	+ (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02),
 	//	- (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04),
 	//	+ (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05),

+ 54 - 0
glm/core/precision.hpp

@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////////
+/// OpenGL Mathematics (glm.g-truc.net)
+///
+/// Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
+/// Permission is hereby granted, free of charge, to any person obtaining a copy
+/// of this software and associated documentation files (the "Software"), to deal
+/// in the Software without restriction, including without limitation the rights
+/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+/// copies of the Software, and to permit persons to whom the Software is
+/// furnished to do so, subject to the following conditions:
+///
+/// The above copyright notice and this permission notice shall be included in
+/// all copies or substantial portions of the Software.
+///
+/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+/// THE SOFTWARE.
+///
+/// @ref core
+/// @file glm/core/precision.hpp
+/// @date 2013-04-01 / 2013-04-01
+/// @author Christophe Riccio
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef GLM_CORE_PRECISION_INCLUDED
+#define GLM_CORE_PRECISION_INCLUDED
+
+namespace glm
+{
+	enum precision
+	{
+		lowp,
+		mediump,
+		highp
+	};
+}//namespace glm
+
+#if(!defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
+#define defaultp		mediump
+#elif(defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
+#define defaultp		highp
+#elif(!defined(GLM_PRECISION_HIGHP_INT) && defined(GLM_PRECISION_MEDIUMP_INT) && !defined(GLM_PRECISION_LOWP_INT))
+#define defaultp		mediump
+#elif(!defined(GLM_PRECISION_HIGHP_INT) && !defined(GLM_PRECISION_MEDIUMP_INT) && defined(GLM_PRECISION_LOWP_INT))
+#define defaultp		lowp
+#else
+#	error "GLM error: multiple default precision requested for signed interger types"
+#endif
+
+#endif//GLM_CORE_PRECISION_INCLUDED

+ 0 - 0
glm/core/precision.inl


+ 22 - 0
glm/core/type_half.hpp

@@ -111,6 +111,28 @@ namespace detail
 		detail::half const & y);
 
 }//namespace detail
+	
+	/// Low half-precision floating-point numbers.
+	typedef detail::half		lowp_half;
+	
+	/// Medium half-precision floating-point numbers.
+	typedef detail::half		mediump_half;
+	
+	/// High half-precision floating-point numbers.
+	typedef detail::half		highp_half;
+	
+#if(!defined(GLM_PRECISION_HIGHP_HALF) && !defined(GLM_PRECISION_MEDIUMP_HALF) && !defined(GLM_PRECISION_LOWP_HALF))
+	typedef mediump_half		half_t;
+#elif(defined(GLM_PRECISION_HIGHP_HALF) && !defined(GLM_PRECISION_MEDIUMP_HALF) && !defined(GLM_PRECISION_LOWP_HALF))
+	typedef highp_half			half_t;
+#elif(!defined(GLM_PRECISION_HIGHP_HALF) && defined(GLM_PRECISION_MEDIUMP_HALF) && !defined(GLM_PRECISION_LOWP_HALF))
+	typedef mediump_half		half_t;
+#elif(!defined(GLM_PRECISION_HIGHP_HALF) && !defined(GLM_PRECISION_MEDIUMP_HALF) && defined(GLM_PRECISION_LOWP_HALF))
+	typedef lowp_half			half_t;
+#else
+#	error "GLM error: Multiple default precisions requested for half-precision floating-point types"
+#endif
+	
 }//namespace glm
 
 #include "type_half.inl"

+ 353 - 58
glm/core/type_mat.hpp

@@ -29,20 +29,20 @@
 #ifndef glm_core_type_mat
 #define glm_core_type_mat
 
-#include "type_gentype.hpp"
+#include "precision.hpp"
 
 namespace glm{
 namespace detail
 {
-	template <typename T> struct tmat2x2;
-	template <typename T> struct tmat2x3;
-	template <typename T> struct tmat2x4;
-	template <typename T> struct tmat3x2;
-	template <typename T> struct tmat3x3;
-	template <typename T> struct tmat3x4;
-	template <typename T> struct tmat4x2;
-	template <typename T> struct tmat4x3;
-	template <typename T> struct tmat4x4;
+	template <typename T, precision P> struct tmat2x2;
+	template <typename T, precision P> struct tmat2x3;
+	template <typename T, precision P> struct tmat2x4;
+	template <typename T, precision P> struct tmat3x2;
+	template <typename T, precision P> struct tmat3x3;
+	template <typename T, precision P> struct tmat3x4;
+	template <typename T, precision P> struct tmat4x2;
+	template <typename T, precision P> struct tmat4x3;
+	template <typename T, precision P> struct tmat4x4;
 	
 	template <typename T>
 	struct is_matrix
@@ -74,42 +74,42 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x2<lowp_float>		lowp_mat2;
+	typedef detail::tmat2x2<float, lowp>		lowp_mat2;
 	
 	/// 2 columns of 2 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x2<mediump_float>	mediump_mat2;
+	typedef detail::tmat2x2<float, mediump>		mediump_mat2;
 	
 	/// 2 columns of 2 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x2<highp_float>	highp_mat2;
+	typedef detail::tmat2x2<float, highp>		highp_mat2;
 	
 	/// 2 columns of 2 components matrix of low precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x2<lowp_float>		lowp_mat2x2;
+	typedef detail::tmat2x2<float, lowp>		lowp_mat2x2;
 	
 	/// 2 columns of 2 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x2<mediump_float>	mediump_mat2x2;
+	typedef detail::tmat2x2<float, mediump>		mediump_mat2x2;
 	
 	/// 2 columns of 2 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x2<highp_float>	highp_mat2x2;
+	typedef detail::tmat2x2<float, highp>		highp_mat2x2;
 	
 	/// @}
 	
@@ -121,21 +121,21 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x3<lowp_float>		lowp_mat2x3;
+	typedef detail::tmat2x3<float, lowp>		lowp_mat2x3;
 	
 	/// 2 columns of 3 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x3<mediump_float>	mediump_mat2x3;
+	typedef detail::tmat2x3<float, mediump>		mediump_mat2x3;
 	
 	/// 2 columns of 3 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x3<highp_float>	highp_mat2x3;
+	typedef detail::tmat2x3<float, highp>		highp_mat2x3;
 	
 	/// @}
 	
@@ -147,21 +147,21 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x4<lowp_float>		lowp_mat2x4;
+	typedef detail::tmat2x4<float, lowp>		lowp_mat2x4;
 	
 	/// 2 columns of 4 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x4<mediump_float>	mediump_mat2x4;
+	typedef detail::tmat2x4<float, mediump>		mediump_mat2x4;
 	
 	/// 2 columns of 4 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat2x4<highp_float>	highp_mat2x4;
+	typedef detail::tmat2x4<float, highp>		highp_mat2x4;
 	
 	/// @}
 	
@@ -173,21 +173,21 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x2<lowp_float>		lowp_mat3x2;
+	typedef detail::tmat3x2<float, lowp>		lowp_mat3x2;
 	
 	/// 3 columns of 2 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x2<mediump_float>	mediump_mat3x2;
+	typedef detail::tmat3x2<float, mediump>		mediump_mat3x2;
 	
 	/// 3 columns of 2 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x2<highp_float>	highp_mat3x2;
+	typedef detail::tmat3x2<float, highp>		highp_mat3x2;
 	
 	/// @}
 	
@@ -199,42 +199,42 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x3<lowp_float>		lowp_mat3;
+	typedef detail::tmat3x3<float, lowp>		lowp_mat3;
 	
 	/// 3 columns of 3 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x3<mediump_float>	mediump_mat3;
+	typedef detail::tmat3x3<float, mediump>		mediump_mat3;
 	
 	/// 3 columns of 3 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x3<highp_float>	highp_mat3;
+	typedef detail::tmat3x3<float, highp>		highp_mat3;
 	
 	/// 3 columns of 3 components matrix of low precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x3<lowp_float>		lowp_mat3x3;
+	typedef detail::tmat3x3<float, lowp>		lowp_mat3x3;
 	
 	/// 3 columns of 3 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x3<mediump_float>	mediump_mat3x3;
+	typedef detail::tmat3x3<float, mediump>		mediump_mat3x3;
 	
 	/// 3 columns of 3 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x3<highp_float>	highp_mat3x3;
+	typedef detail::tmat3x3<float, highp>		highp_mat3x3;
 	
 	/// @}
 	
@@ -246,21 +246,21 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x4<lowp_float>		lowp_mat3x4;
+	typedef detail::tmat3x4<float, lowp>		lowp_mat3x4;
 	
 	/// 3 columns of 4 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x4<mediump_float>	mediump_mat3x4;
+	typedef detail::tmat3x4<float, mediump>		mediump_mat3x4;
 	
 	/// 3 columns of 4 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat3x4<highp_float>	highp_mat3x4;
+	typedef detail::tmat3x4<float, highp>		highp_mat3x4;
 	
 	/// @}
 	
@@ -272,21 +272,21 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x2<lowp_float>		lowp_mat4x2;
+	typedef detail::tmat4x2<float, lowp>		lowp_mat4x2;
 	
 	/// 4 columns of 2 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x2<mediump_float>	mediump_mat4x2;
+	typedef detail::tmat4x2<float, mediump>		mediump_mat4x2;
 	
 	/// 4 columns of 2 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x2<highp_float>	highp_mat4x2;
+	typedef detail::tmat4x2<float, highp>		highp_mat4x2;
 	
 	/// @}
 	
@@ -298,21 +298,21 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x3<lowp_float>		lowp_mat4x3;
+	typedef detail::tmat4x3<float, lowp>		lowp_mat4x3;
 	
 	/// 4 columns of 3 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x3<mediump_float>	mediump_mat4x3;
+	typedef detail::tmat4x3<float, mediump>		mediump_mat4x3;
 	
 	/// 4 columns of 3 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x3<highp_float>	highp_mat4x3;
+	typedef detail::tmat4x3<float, highp>		highp_mat4x3;
 	
 	/// @}
 	
@@ -325,42 +325,42 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x4<lowp_float>		lowp_mat4;
+	typedef detail::tmat4x4<float, lowp>		lowp_mat4;
 	
 	/// 4 columns of 4 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x4<mediump_float>	mediump_mat4;
+	typedef detail::tmat4x4<float, mediump>		mediump_mat4;
 	
 	/// 4 columns of 4 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x4<highp_float>	highp_mat4;
+	typedef detail::tmat4x4<float, highp>		highp_mat4;
 	
 	/// 4 columns of 4 components matrix of low precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x4<lowp_float>		lowp_mat4x4;
+	typedef detail::tmat4x4<float, lowp>		lowp_mat4x4;
 	
 	/// 4 columns of 4 components matrix of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x4<mediump_float>	mediump_mat4x4;
+	typedef detail::tmat4x4<float, mediump>		mediump_mat4x4;
 	
 	/// 4 columns of 4 components matrix of high precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
 	/// @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::tmat4x4<highp_float>	highp_mat4x4;
+	typedef detail::tmat4x4<float, highp>		highp_mat4x4;
 	
 	/// @}
 	
@@ -466,65 +466,360 @@ namespace detail
 	//////////////////////////
 	// Double definition
 	
+	/// @addtogroup core_precision
+	/// @{
+	
+	/// 2 columns of 2 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x2<double, lowp>		lowp_dmat2;
+	
+	/// 2 columns of 2 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x2<double, mediump>	mediump_dmat2;
+	
+	/// 2 columns of 2 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x2<double, highp>		highp_dmat2;
+	
+	/// 2 columns of 2 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x2<double, lowp>		lowp_dmat2x2;
+	
+	/// 2 columns of 2 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x2<double, mediump>	mediump_dmat2x2;
+	
+	/// 2 columns of 2 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x2<double, highp>		highp_dmat2x2;
+	
+	/// @}
+	
+	/// @addtogroup core_precision
+	/// @{
+	
+	/// 2 columns of 3 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x3<double, lowp>		lowp_dmat2x3;
+	
+	/// 2 columns of 3 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x3<double, mediump>	mediump_dmat2x3;
+	
+	/// 2 columns of 3 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x3<double, highp>		highp_dmat2x3;
+	
+	/// @}
+	
+	/// @addtogroup core_precision
+	/// @{
+	
+	/// 2 columns of 4 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x4<double, lowp>		lowp_dmat2x4;
+	
+	/// 2 columns of 4 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x4<double, mediump>	mediump_dmat2x4;
+	
+	/// 2 columns of 4 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat2x4<double, highp>		highp_dmat2x4;
+	
+	/// @}
+	
+	/// @addtogroup core_precision
+	/// @{
+	
+	/// 3 columns of 2 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x2<double, lowp>		lowp_dmat3x2;
+	
+	/// 3 columns of 2 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x2<double, mediump>	mediump_dmat3x2;
+	
+	/// 3 columns of 2 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x2<double, highp>		highp_dmat3x2;
+	
+	/// @}
+	
+	/// @addtogroup core_precision
+	/// @{
+	
+	/// 3 columns of 3 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x3<float, lowp>		lowp_dmat3;
+	
+	/// 3 columns of 3 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x3<double, mediump>	mediump_dmat3;
+	
+	/// 3 columns of 3 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x3<double, highp>		highp_dmat3;
+	
+	/// 3 columns of 3 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x3<double, lowp>		lowp_dmat3x3;
+	
+	/// 3 columns of 3 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x3<double, mediump>	mediump_dmat3x3;
+	
+	/// 3 columns of 3 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x3<double, highp>		highp_dmat3x3;
+	
+	/// @}
+	
+	/// @addtogroup core_precision
+	/// @{
+	
+	/// 3 columns of 4 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x4<double, lowp>		lowp_dmat3x4;
+	
+	/// 3 columns of 4 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x4<double, mediump>	mediump_dmat3x4;
+	
+	/// 3 columns of 4 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat3x4<double, highp>		highp_dmat3x4;
+	
+	/// @}
+	
+	/// @addtogroup core_precision
+	/// @{
+	
+	/// 4 columns of 2 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x2<double, lowp>		lowp_dmat4x2;
+	
+	/// 4 columns of 2 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x2<double, mediump>	mediump_dmat4x2;
+	
+	/// 4 columns of 2 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x2<double, highp>		highp_dmat4x2;
+	
+	/// @}
+	
+	/// @addtogroup core_precision
+	/// @{
+	
+	/// 4 columns of 3 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x3<double, lowp>		lowp_dmat4x3;
+	
+	/// 4 columns of 3 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x3<double, mediump>	mediump_dmat4x3;
+	
+	/// 4 columns of 3 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x3<double, highp>		highp_dmat4x3;
+	
+	/// @}
+	
+	/// @addtogroup core_precision
+	/// @{
+	
+	/// 4 columns of 4 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x4<double, lowp>		lowp_dmat4;
+	
+	/// 4 columns of 4 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x4<double, mediump>	mediump_dmat4;
+	
+	/// 4 columns of 4 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x4<double, highp>		highp_dmat4;
+	
+	/// 4 columns of 4 components matrix of low precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x4<double, lowp>		lowp_dmat4x4;
+	
+	/// 4 columns of 4 components matrix of medium precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x4<double, mediump>	mediump_dmat4x4;
+	
+	/// 4 columns of 4 components matrix of high precision floating-point numbers.
+	///
+	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
+	/// @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::tmat4x4<double, highp>		highp_dmat4x4;
+	
+	/// @}
+	
+#if(defined(GLM_PRECISION_HIGHP_DOUBLE))
+	typedef highp_dmat2x2		dmat2x2;
+	typedef highp_dmat2x3		dmat2x3;
+	typedef highp_dmat2x4		dmat2x4;
+	typedef highp_dmat3x2		dmat3x2;
+	typedef highp_dmat3x3		dmat3x3;
+	typedef highp_dmat3x4		dmat3x4;
+	typedef highp_dmat4x2		dmat4x2;
+	typedef highp_dmat4x3		dmat4x3;
+	typedef highp_dmat4x4		dmat4x4;
+#elif(defined(GLM_PRECISION_MEDIUMP_DOUBLE))
+	typedef mediump_dmat2x2		dmat2x2;
+	typedef mediump_dmat2x3		dmat2x3;
+	typedef mediump_dmat2x4		dmat2x4;
+	typedef mediump_dmat3x2		dmat3x2;
+	typedef mediump_dmat3x3		dmat3x3;
+	typedef mediump_dmat3x4		dmat3x4;
+	typedef mediump_dmat4x2		dmat4x2;
+	typedef mediump_dmat4x3		dmat4x3;
+	typedef mediump_dmat4x4		dmat4x4;
+#elif(defined(GLM_PRECISION_LOWP_DOUBLE))
+	typedef lowp_dmat2x2		dmat2x2;
+	typedef lowp_dmat2x3		dmat2x3;
+	typedef lowp_dmat2x4		dmat2x4;
+	typedef lowp_dmat3x2		dmat3x2;
+	typedef lowp_dmat3x3		dmat3x3;
+	typedef lowp_dmat3x4		dmat3x4;
+	typedef lowp_dmat4x2		dmat4x2;
+	typedef lowp_dmat4x3		dmat4x3;
+	typedef lowp_dmat4x4		dmat4x4;
+#else
+	
 	//! 2 * 2 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat2x2<double>	dmat2;
+	typedef mediump_dmat2x2		dmat2;
 	
 	//! 3 * 3 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat3x3<double>	dmat3;
+	typedef mediump_dmat3x3		dmat3;
 	
 	//! 4 * 4 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat4x4<double>	dmat4;
+	typedef mediump_dmat4x4		dmat4;
 	
 	//! 2 * 2 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat2x2<double>	dmat2x2;
+	typedef mediump_dmat2x2		dmat2x2;
 	
 	//! 2 * 3 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat2x3<double>	dmat2x3;
+	typedef mediump_dmat2x3		dmat2x3;
 	
 	//! 2 * 4 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat2x4<double>	dmat2x4;
+	typedef mediump_dmat2x4		dmat2x4;
 	
 	//! 3 * 2 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat3x2<double>	dmat3x2;
+	typedef mediump_dmat3x2		dmat3x2;
 	
 	/// 3 * 3 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat3x3<double>	dmat3x3;
+	typedef mediump_dmat3x3		dmat3x3;
 	
 	/// 3 * 4 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat3x4<double>	dmat3x4;
+	typedef mediump_dmat3x4		dmat3x4;
 	
 	/// 4 * 2 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat4x2<double>	dmat4x2;
+	typedef mediump_dmat4x2		dmat4x2;
 	
 	/// 4 * 3 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat4x3<double>	dmat4x3;
+	typedef mediump_dmat4x3		dmat4x3;
 	
 	/// 4 * 4 matrix of double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.6 Matrices</a>
-	typedef detail::tmat4x4<double>	dmat4x4;
+	typedef mediump_dmat4x4		dmat4x4;
+
+#endif//GLM_PRECISION
 	
 	/// @}
 }//namespace glm

+ 125 - 125
glm/core/type_mat2x2.hpp

@@ -35,17 +35,17 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> 
+	template <typename T, precision P>
 	struct tmat2x2
 	{
 		// Implementation detail
 		enum ctor{null};
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec2<T> col_type;
-		typedef tvec2<T> row_type;
-		typedef tmat2x2<T> type;
-		typedef tmat2x2<T> transpose_type;
+		typedef tvec2<T, P> col_type;
+		typedef tvec2<T, P> row_type;
+		typedef tmat2x2<T, P> type;
+		typedef tmat2x2<T, P> transpose_type;
 
 		static GLM_FUNC_DECL size_type col_size();
 		static GLM_FUNC_DECL size_type row_size();
@@ -54,7 +54,7 @@ namespace detail
 
 	public:
 		// Implementation detail
-		GLM_FUNC_DECL tmat2x2<T> _inverse() const;
+		GLM_FUNC_DECL tmat2x2<T, P> _inverse() const;
 
 	private:
 		//////////////////////////////////////
@@ -92,22 +92,22 @@ namespace detail
 			
 		template <typename U, typename V> 
 		GLM_FUNC_DECL explicit tmat2x2(
-			tvec2<U> const & v1, 
-			tvec2<V> const & v2);
+			tvec2<U, P> const & v1,
+			tvec2<V, P> const & v2);
 
 		//////////////////////////////////////
 		// Matrix conversions
 		template <typename U> 
-		GLM_FUNC_DECL explicit tmat2x2(tmat2x2<U> const & m);
+		GLM_FUNC_DECL explicit tmat2x2(tmat2x2<U, P> const & m);
 
-		GLM_FUNC_DECL explicit tmat2x2(tmat3x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x2(tmat4x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x2(tmat2x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x2(tmat3x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x2(tmat2x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x2(tmat4x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x2(tmat3x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x2(tmat4x3<T> const & x);
+		GLM_FUNC_DECL explicit tmat2x2(tmat3x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x2(tmat4x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x2(tmat2x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x2(tmat3x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x2(tmat2x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x2(tmat4x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x2(tmat3x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x2(tmat4x3<T, P> const & x);
 
 		//////////////////////////////////////
 		// Accesses
@@ -116,133 +116,133 @@ namespace detail
 		GLM_FUNC_DECL col_type const & operator[](size_type i) const;
 
 		// Unary updatable operators
-		GLM_FUNC_DECL tmat2x2<T> & operator=(tmat2x2<T> const & m);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator=(tmat2x2<T, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x2<T> & operator=(tmat2x2<U> const & m);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator=(tmat2x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x2<T> & operator+=(U const & s);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator+=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x2<T> & operator+=(tmat2x2<U> const & m);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator+=(tmat2x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x2<T> & operator-=(U const & s);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator-=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x2<T> & operator-=(tmat2x2<U> const & m);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator-=(tmat2x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x2<T> & operator*=(U const & s);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator*=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x2<T> & operator*=(tmat2x2<U> const & m);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator*=(tmat2x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x2<T> & operator/=(U const & s);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator/=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x2<T> & operator/=(tmat2x2<U> const & m);
-		GLM_FUNC_DECL tmat2x2<T> & operator++();
-		GLM_FUNC_DECL tmat2x2<T> & operator--();
+		GLM_FUNC_DECL tmat2x2<T, P> & operator/=(tmat2x2<U, P> const & m);
+		GLM_FUNC_DECL tmat2x2<T, P> & operator++();
+		GLM_FUNC_DECL tmat2x2<T, P> & operator--();
 	};
 
 	// Binary operators
-	template <typename T> 
-	tmat2x2<T> operator+ (
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x2<T> operator+ (
-		typename tmat2x2<T>::value_type const & s, 
-		tmat2x2<T> const & m);
-
-	template <typename T> 
-	tmat2x2<T> operator+ (
-		tmat2x2<T> const & m1, 
-		tmat2x2<T> const & m2);
-
-	template <typename T> 
-	tmat2x2<T> operator- (
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x2<T> operator- (
-		typename tmat2x2<T>::value_type const & s, 
-		tmat2x2<T> const & m);
-
-	template <typename T> 
-	tmat2x2<T> operator- (
-		tmat2x2<T> const & m1, 
-		tmat2x2<T> const & m2);
-
-	template <typename T> 
-	tmat2x2<T> operator* (
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x2<T> operator* (
-		typename tmat2x2<T>::value_type const & s, 
-		tmat2x2<T> const & m);
-
-	template <typename T> 
-	typename tmat2x2<T>::col_type operator* (
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::row_type const & v);
-
-	template <typename T> 
-	typename tmat2x2<T>::row_type operator* (
-		typename tmat2x2<T>::col_type const & v, 
-		tmat2x2<T> const & m);
-
-	template <typename T> 
-	tmat2x2<T> operator* (
-		tmat2x2<T> const & m1, 
-		tmat2x2<T> const & m2);
+	template <typename T, precision P>
+	tmat2x2<T, P> operator+ (
+		tmat2x2<T, P> const & m,
+		typename tmat2x2<T, P>::value_type const & s);
+
+	template <typename T, precision P> 
+	tmat2x2<T, P> operator+ (
+		typename tmat2x2<T, P>::value_type const & s,
+		tmat2x2<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat2x2<T, P> operator+ (
+		tmat2x2<T, P> const & m1,
+		tmat2x2<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat2x2<T, P> operator- (
+		tmat2x2<T, P> const & m,
+		typename tmat2x2<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat2x2<T, P> operator- (
+		typename tmat2x2<T, P>::value_type const & s,
+		tmat2x2<T, P> const & m);
+
+	template <typename T, precision P> 
+	tmat2x2<T, P> operator- (
+		tmat2x2<T, P> const & m1, 
+		tmat2x2<T, P> const & m2);
+
+	template <typename T, precision P> 
+	tmat2x2<T, P> operator* (
+		tmat2x2<T, P> const & m, 
+		typename tmat2x2<T, P>::value_type const & s);
+
+	template <typename T, precision P> 
+	tmat2x2<T, P> operator* (
+		typename tmat2x2<T, P>::value_type const & s, 
+		tmat2x2<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat2x2<T, P>::col_type operator* (
+		tmat2x2<T, P> const & m,
+		typename tmat2x2<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat2x2<T, P>::row_type operator* (
+		typename tmat2x2<T, P>::col_type const & v,
+		tmat2x2<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat2x2<T, P> operator* (
+		tmat2x2<T, P> const & m1,
+		tmat2x2<T, P> const & m2);
 		
-	template <typename T>
-	tmat3x2<T> operator* (
-		tmat2x2<T> const & m1, 
-		tmat3x2<T> const & m2);
+	template <typename T, precision P>
+	tmat3x2<T, P> operator* (
+		tmat2x2<T, P> const & m1,
+		tmat3x2<T, P> const & m2);
 		
-	template <typename T>
-	tmat4x2<T> operator* (
-		tmat2x2<T> const & m1, 
-		tmat4x2<T> const & m2);
-
-	template <typename T> 
-	tmat2x2<T> operator/ (
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x2<T> operator/ (
-		typename tmat2x2<T>::value_type const & s,
-		tmat2x2<T> const & m);
-
-	template <typename T> 
-	typename tmat2x2<T>::col_type operator/ (
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::row_type const & v);
-
-	template <typename T> 
-	typename tmat2x2<T>::row_type operator/ (
-		typename tmat2x2<T>::col_type const & v, 
-		tmat2x2<T> const & m);
-
-	template <typename T> 
-	tmat2x2<T> operator/ (
-		tmat2x2<T> const & m1, 
-		tmat2x2<T> const & m2);
+	template <typename T, precision P>
+	tmat4x2<T, P> operator* (
+		tmat2x2<T, P> const & m1,
+		tmat4x2<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat2x2<T, P> operator/ (
+		tmat2x2<T, P> const & m,
+		typename tmat2x2<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat2x2<T, P> operator/ (
+		typename tmat2x2<T, P>::value_type const & s,
+		tmat2x2<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat2x2<T, P>::col_type operator/ (
+		tmat2x2<T, P> const & m,
+		typename tmat2x2<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat2x2<T, P>::row_type operator/ (
+		typename tmat2x2<T, P>::col_type const & v,
+		tmat2x2<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat2x2<T, P> operator/ (
+		tmat2x2<T, P> const & m1,
+		tmat2x2<T, P> const & m2);
 
 	// Unary constant operators
-	template <typename T> 
-	tmat2x2<T> const operator-  (
-		tmat2x2<T> const & m);
+	template <typename T, precision P> 
+	tmat2x2<T, P> const operator-  (
+		tmat2x2<T, P> const & m);
 
-	template <typename T> 
-	tmat2x2<T> const operator-- (
-		tmat2x2<T> const & m, 
+	template <typename T, precision P> 
+	tmat2x2<T, P> const operator-- (
+		tmat2x2<T, P> const & m, 
 		int);
 
-	template <typename T> 
-	tmat2x2<T> const operator++ (
-		tmat2x2<T> const & m, 
+	template <typename T, precision P> 
+	tmat2x2<T, P> const operator++ (
+		tmat2x2<T, P> const & m, 
 		int);
 } //namespace detail
 } //namespace glm

+ 210 - 210
glm/core/type_mat2x2.inl

@@ -29,20 +29,20 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat2x2<T>::size_type tmat2x2<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat2x2<T, P>::size_type tmat2x2<T, P>::length() const
 	{
 		return 2;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x2<T>::size_type tmat2x2<T>::col_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::size_type tmat2x2<T, P>::col_size()
 	{
 		return 2;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x2<T>::size_type tmat2x2<T>::row_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::size_type tmat2x2<T, P>::row_size()
 	{
 		return 2;
 	}
@@ -50,9 +50,9 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x2<T>::col_type &
-	tmat2x2<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type &
+	tmat2x2<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -61,9 +61,9 @@ namespace detail
 		return this->value[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x2<T>::col_type const &
-	tmat2x2<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type const &
+	tmat2x2<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -75,32 +75,32 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Constructors
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2()
 	{
 		this->value[0] = col_type(1, 0);
 		this->value[1] = col_type(0, 1);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
 		this->value[0] = m.value[0];
 		this->value[1] = m.value[1];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
 		ctor
 	)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
 		value_type const & s
 	)
@@ -110,10 +110,10 @@ namespace detail
 		this->value[1] = col_type(Zero, s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		value_type const & x0, value_type const & y0, 
+		value_type const & x0, value_type const & y0,
 		value_type const & x1, value_type const & y1
 	)
 	{
@@ -121,10 +121,10 @@ namespace detail
 		this->value[1] = col_type(x1, y1);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		col_type const & v0, 
+		col_type const & v0,
 		col_type const & v1
 	)
 	{
@@ -134,23 +134,23 @@ namespace detail
 
 	//////////////////////////////////////
 	// Convertion constructors
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_DECL tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_DECL tmat2x2<T, P>::tmat2x2
 	(
 		U const & s
 	)
 	{
 		value_type const Zero(0);
-		this->value[0] = tvec2<T>(value_type(s), Zero);
-		this->value[1] = tvec2<T>(Zero, value_type(s));
+		this->value[0] = tvec2<T, P>(value_type(s), Zero);
+		this->value[1] = tvec2<T, P>(Zero, value_type(s));
 	}
 	
-	template <typename T> 
-	template <typename X1, typename Y1, typename X2, typename Y2> 
-	GLM_FUNC_DECL tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	template <typename X1, typename Y1, typename X2, typename Y2>
+	GLM_FUNC_DECL tmat2x2<T, P>::tmat2x2
 	(
-		X1 const & x1, Y1 const & y1, 
+		X1 const & x1, Y1 const & y1,
 		X2 const & x2, Y2 const & y2
 	)
 	{
@@ -158,12 +158,12 @@ namespace detail
 		this->value[1] = col_type(value_type(x2), value_type(y2));
 	}
 	
-	template <typename T> 
-	template <typename V1, typename V2> 
-	GLM_FUNC_DECL tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	template <typename V1, typename V2>
+	GLM_FUNC_DECL tmat2x2<T, P>::tmat2x2
 	(
-		tvec2<V1> const & v1, 
-		tvec2<V2> const & v2
+		tvec2<V1, P> const & v1,
+		tvec2<V2, P> const & v2
 	)
 	{
 		this->value[0] = col_type(v1);
@@ -173,103 +173,103 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// mat2x2 matrix conversions
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat2x2<U> const & m
+		tmat2x2<U, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
 		this->value[1] = m[1];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
 		this->value[1] = m[1];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>::tmat2x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>::tmat2x2
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T> tmat2x2<T>::_inverse() const
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> tmat2x2<T, P>::_inverse() const
 	{
-		typename tmat2x2<T>::value_type Determinant = this->value[0][0] * this->value[1][1] - this->value[1][0] * this->value[0][1];
+		typename tmat2x2<T, P>::value_type Determinant = this->value[0][0] * this->value[1][1] - this->value[1][0] * this->value[0][1];
 
-		tmat2x2<T> Inverse(
+		tmat2x2<T, P> Inverse(
 			+ this->value[1][1] / Determinant,
 			- this->value[0][1] / Determinant,
 			- this->value[1][0] / Determinant, 
@@ -281,10 +281,10 @@ namespace detail
 	// mat2x2 operators
 
 	// This function shouldn't required but it seems that VC7.1 have an optimisation bug if this operator wasn't declared
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator=
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator=
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -292,11 +292,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator=
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator=
 	(
-		tmat2x2<U> const & m
+		tmat2x2<U, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -304,9 +304,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator+=
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator+=
 	(
 		U const & s
 	)
@@ -316,11 +316,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator+=
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator+=
 	(
-		tmat2x2<U> const & m
+		tmat2x2<U, P> const & m
 	)
 	{
 		this->value[0] += m[0];
@@ -328,9 +328,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator-=
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator-=
 	(
 		U const & s
 	)
@@ -340,11 +340,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator-=
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator-=
 	(
-		tmat2x2<U> const & m
+		tmat2x2<U, P> const & m
 	)
 	{
 		this->value[0] -= m[0];
@@ -352,9 +352,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator*= 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator*= 
 	(
 		U const & s
 	)
@@ -364,19 +364,19 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator*= 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator*= 
 	(
-		tmat2x2<U> const & m
+		tmat2x2<U, P> const & m
 	)
 	{
 		return (*this = *this * m);
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator/= 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator/= 
 	(
 		U const & s
 	)
@@ -386,26 +386,26 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator/= 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator/= 
 	(
-		tmat2x2<U> const & m
+		tmat2x2<U, P> const & m
 	)
 	{
 		return (*this = *this / m);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator++ ()
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator++ ()
 	{
 		++this->value[0];
 		++this->value[1];
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T>& tmat2x2<T>::operator-- ()
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P>& tmat2x2<T, P>::operator-- ()
 	{
 		--this->value[0];
 		--this->value[1];
@@ -415,148 +415,148 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Binary operators
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+ 
 	(
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::value_type const & s
+		tmat2x2<T, P> const & m, 
+		typename tmat2x2<T, P>::value_type const & s
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m[0] + s,
 			m[1] + s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+ 
 	(
-		typename tmat2x2<T>::value_type const & s, 
-		tmat2x2<T> const & m
+		typename tmat2x2<T, P>::value_type const & s, 
+		tmat2x2<T, P> const & m
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m[0] + s,
 			m[1] + s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator+ 
 	(
-		tmat2x2<T> const & m1, 
-		tmat2x2<T> const & m2
+		tmat2x2<T, P> const & m1, 
+		tmat2x2<T, P> const & m2
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m1[0] + m2[0],
 			m1[1] + m2[1]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator- 
 	(
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::value_type const & s
+		tmat2x2<T, P> const & m, 
+		typename tmat2x2<T, P>::value_type const & s
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m[0] - s,
 			m[1] - s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator- 
 	(
-		typename tmat2x2<T>::value_type const & s, 
-		tmat2x2<T> const & m
+		typename tmat2x2<T, P>::value_type const & s, 
+		tmat2x2<T, P> const & m
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			s - m[0],
 			s - m[1]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator- 
 	(
-		tmat2x2<T> const & m1, 
-		tmat2x2<T> const & m2
+		tmat2x2<T, P> const & m1, 
+		tmat2x2<T, P> const & m2
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m1[0] - m2[0],
 			m1[1] - m2[1]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator* 
 	(
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::value_type const & s
+		tmat2x2<T, P> const & m, 
+		typename tmat2x2<T, P>::value_type const & s
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m[0] * s,
 			m[1] * s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator* 
 	(	
-		typename tmat2x2<T>::value_type const & s, 
-		tmat2x2<T> const & m
+		typename tmat2x2<T, P>::value_type const & s, 
+		tmat2x2<T, P> const & m
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m[0] * s,
 			m[1] * s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x2<T>::col_type operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type operator*
 	(
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::row_type const & v
+		tmat2x2<T, P> const & m, 
+		typename tmat2x2<T, P>::row_type const & v
 	)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			m[0][0] * v.x + m[1][0] * v.y,
 			m[0][1] * v.x + m[1][1] * v.y);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x2<T>::row_type operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::row_type operator*
 	(
-		typename tmat2x2<T>::col_type const & v, 
-		tmat2x2<T> const & m
+		typename tmat2x2<T, P>::col_type const & v, 
+		tmat2x2<T, P> const & m
 	)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			v.x * m[0][0] + v.y * m[0][1],
 			v.x * m[1][0] + v.y * m[1][1]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator*
 	(
-		tmat2x2<T> const & m1,
-		tmat2x2<T> const & m2
+		tmat2x2<T, P> const & m1,
+		tmat2x2<T, P> const & m2
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
 			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
 			m1[0][1] * m2[1][0] + m1[1][1] * m2[1][1]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator*
 	(
-		tmat2x2<T> const & m1, 
-		tmat3x2<T> const & m2
+		tmat2x2<T, P> const & m1,
+		tmat3x2<T, P> const & m2
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
 			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
@@ -565,14 +565,14 @@ namespace detail
 			m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator*
 	(
-		tmat2x2<T> const & m1, 
-		tmat4x2<T> const & m2
+		tmat2x2<T, P> const & m1,
+		tmat4x2<T, P> const & m2
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
 			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1],
@@ -583,92 +583,92 @@ namespace detail
 			m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator/ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator/
 	(
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::value_type const & s
+		tmat2x2<T, P> const & m,
+		typename tmat2x2<T, P>::value_type const & s
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m[0] / s,
 			m[1] / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator/ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator/
 	(
-		typename tmat2x2<T>::value_type const & s, 
-		tmat2x2<T> const & m
+		typename tmat2x2<T, P>::value_type const & s,
+		tmat2x2<T, P> const & m
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			s / m[0],
 			s / m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat2x2<T>::col_type operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::col_type operator/
 	(
-		tmat2x2<T> const & m, 
-		typename tmat2x2<T>::row_type & v
+		tmat2x2<T, P> const & m, 
+		typename tmat2x2<T, P>::row_type & v
 	)
 	{
 		return m._inverse() * v;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat2x2<T>::row_type operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x2<T, P>::row_type operator/ 
 	(
-		typename tmat2x2<T>::col_type const & v,
-		tmat2x2<T> const & m
+		typename tmat2x2<T, P>::col_type const & v,
+		tmat2x2<T, P> const & m
 	)
 	{
 		return v * m._inverse();
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator/
 	(
-		tmat2x2<T> const & m1, 
-		tmat2x2<T> const & m2
+		tmat2x2<T, P> const & m1, 
+		tmat2x2<T, P> const & m2
 	)
 	{
 		return m1 * m2._inverse();
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T> const operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> const operator-
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			-m[0], 
 			-m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T> const operator++ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> const operator++
 	(
-		tmat2x2<T> const & m, 
+		tmat2x2<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m[0] + T(1),
 			m[1] + T(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T> const operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> const operator--
 	(
-		tmat2x2<T> const & m, 
+		tmat2x2<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat2x2<T>(
+		return tmat2x2<T, P>(
 			m[0] - T(1),
 			m[1] - T(1));
 	}
@@ -676,21 +676,21 @@ namespace detail
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tmat2x2<T> const & m1, 
-		tmat2x2<T> const & m2
+		tmat2x2<T, P> const & m1,
+		tmat2x2<T, P> const & m2
 	)
 	{
 		return (m1[0] == m2[0]) && (m1[1] == m2[1]);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tmat2x2<T> const & m1, 
-		tmat2x2<T> const & m2
+		tmat2x2<T, P> const & m1,
+		tmat2x2<T, P> const & m2
 	)
 	{
 		return (m1[0] != m2[0]) || (m1[1] != m2[1]);

+ 102 - 102
glm/core/type_mat2x3.hpp

@@ -35,16 +35,16 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> 
+	template <typename T, precision P>
 	struct tmat2x3
 	{
 		enum ctor{null};
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec3<T> col_type;
-		typedef tvec2<T> row_type;
-		typedef tmat2x3<T> type;
-		typedef tmat3x2<T> transpose_type;
+		typedef tvec3<T, P> col_type;
+		typedef tvec2<T, P> row_type;
+		typedef tmat2x3<T, P> type;
+		typedef tmat3x2<T, P> transpose_type;
 
 		static GLM_FUNC_DECL size_type col_size();
 		static GLM_FUNC_DECL size_type row_size();
@@ -68,145 +68,145 @@ namespace detail
 			value_type const & x0, value_type const & y0, value_type const & z0,
 			value_type const & x1, value_type const & y1, value_type const & z1);
 		GLM_FUNC_DECL explicit tmat2x3(
-			col_type const & v0, 
+			col_type const & v0,
 			col_type const & v1);
 
 		//////////////////////////////////////
 		// Conversions
-		template <typename U> 
+		template <typename U>
 		GLM_FUNC_DECL explicit tmat2x3(
 			U const & x);
 			
-		template <typename X1, typename Y1, typename Z1, typename X2, typename Y2, typename Z2> 
+		template <typename X1, typename Y1, typename Z1, typename X2, typename Y2, typename Z2>
 		GLM_FUNC_DECL explicit tmat2x3(
-			X1 const & x1, Y1 const & y1, Z1 const & z1, 
+			X1 const & x1, Y1 const & y1, Z1 const & z1,
 			X2 const & x2, Y2 const & y2, Z2 const & z2);
 			
-		template <typename U, typename V> 
+		template <typename U, typename V>
 		GLM_FUNC_DECL explicit tmat2x3(
-			tvec3<U> const & v1, 
-			tvec3<V> const & v2);
+			tvec3<U, P> const & v1,
+			tvec3<V, P> const & v2);
 
 		//////////////////////////////////////
 		// Matrix conversion
 		template <typename U> 
-		GLM_FUNC_DECL explicit tmat2x3(tmat2x3<U> const & m);
+		GLM_FUNC_DECL explicit tmat2x3(tmat2x3<U, P> const & m);
 
-		GLM_FUNC_DECL explicit tmat2x3(tmat2x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x3(tmat3x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x3(tmat4x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x3(tmat2x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x3(tmat3x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x3(tmat3x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x3(tmat4x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x3(tmat4x3<T> const & x);
+		GLM_FUNC_DECL explicit tmat2x3(tmat2x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x3(tmat3x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x3(tmat4x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x3(tmat2x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x3(tmat3x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x3(tmat3x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x3(tmat4x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x3(tmat4x3<T, P> const & x);
 
 		// Accesses
 		col_type & operator[](size_type i);
 		col_type const & operator[](size_type i) const;
 
 		// Unary updatable operators
-		GLM_FUNC_DECL tmat2x3<T> & operator=  (tmat2x3<T> const & m);
+		GLM_FUNC_DECL tmat2x3<T, P> & operator=  (tmat2x3<T, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x3<T> & operator=  (tmat2x3<U> const & m);
+		GLM_FUNC_DECL tmat2x3<T, P> & operator=  (tmat2x3<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x3<T> & operator+= (U const & s);
+		GLM_FUNC_DECL tmat2x3<T, P> & operator+= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x3<T> & operator+= (tmat2x3<U> const & m);
+		GLM_FUNC_DECL tmat2x3<T, P> & operator+= (tmat2x3<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x3<T> & operator-= (U const & s);
+		GLM_FUNC_DECL tmat2x3<T, P> & operator-= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x3<T> & operator-= (tmat2x3<U> const & m);
+		GLM_FUNC_DECL tmat2x3<T, P> & operator-= (tmat2x3<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x3<T> & operator*= (U const & s);
+		GLM_FUNC_DECL tmat2x3<T, P> & operator*= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x3<T> & operator*= (tmat2x3<U> const & m);
+		GLM_FUNC_DECL tmat2x3<T, P> & operator*= (tmat2x3<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x3<T> & operator/= (U const & s);
+		GLM_FUNC_DECL tmat2x3<T, P> & operator/= (U const & s);
 
-		GLM_FUNC_DECL tmat2x3<T> & operator++ ();
-		GLM_FUNC_DECL tmat2x3<T> & operator-- ();
+		GLM_FUNC_DECL tmat2x3<T, P> & operator++ ();
+		GLM_FUNC_DECL tmat2x3<T, P> & operator-- ();
 	};
 
 	// Binary operators
-	template <typename T> 
-	tmat2x3<T> operator+ (
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x3<T> operator+ (
-		tmat2x3<T> const & m1, 
-		tmat2x3<T> const & m2);
-
-	template <typename T> 
-	tmat2x3<T> operator- (
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x3<T> operator- (
-		tmat2x3<T> const & m1, 
-		tmat2x3<T> const & m2);
-
-	template <typename T> 
-	tmat2x3<T> operator* (
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x3<T> operator* (
-		typename tmat2x3<T>::value_type const & s, 
-		tmat2x3<T> const & m);
-
-	template <typename T>
-	typename tmat2x3<T>::col_type operator* (
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::row_type const & v);
-
-	template <typename T> 
-	typename tmat2x3<T>::row_type operator* (
-		typename tmat2x3<T>::col_type const & v, 
-		tmat2x3<T> const & m);
-
-	template <typename T>
-	tmat2x3<T> operator* (
-		tmat2x3<T> const & m1, 
-		tmat2x2<T> const & m2);
-
-	template <typename T>
-	tmat3x3<T> operator* (
-		tmat2x3<T> const & m1, 
-		tmat3x2<T> const & m2);
+	template <typename T, precision P>
+	tmat2x3<T, P> operator+ (
+		tmat2x3<T, P> const & m,
+		typename tmat2x3<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat2x3<T, P> operator+ (
+		tmat2x3<T, P> const & m1,
+		tmat2x3<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat2x3<T, P> operator- (
+		tmat2x3<T, P> const & m,
+		typename tmat2x3<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat2x3<T, P> operator- (
+		tmat2x3<T, P> const & m1,
+		tmat2x3<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat2x3<T, P> operator* (
+		tmat2x3<T, P> const & m,
+		typename tmat2x3<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat2x3<T, P> operator* (
+		typename tmat2x3<T, P>::value_type const & s,
+		tmat2x3<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat2x3<T, P>::col_type operator* (
+		tmat2x3<T, P> const & m, 
+		typename tmat2x3<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat2x3<T, P>::row_type operator* (
+		typename tmat2x3<T, P>::col_type const & v,
+		tmat2x3<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat2x3<T, P> operator* (
+		tmat2x3<T, P> const & m1,
+		tmat2x2<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator* (
+		tmat2x3<T, P> const & m1,
+		tmat3x2<T, P> const & m2);
 		
-	template <typename T>
-	tmat4x3<T> operator* (
-		tmat2x3<T> const & m1, 
-		tmat4x2<T> const & m2);
+	template <typename T, precision P>
+	tmat4x3<T, P> operator* (
+		tmat2x3<T, P> const & m1,
+		tmat4x2<T, P> const & m2);
 
-	template <typename T> 
-	tmat2x3<T> operator/ (
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::value_type const & s);
+	template <typename T, precision P>
+	tmat2x3<T, P> operator/ (
+		tmat2x3<T, P> const & m,
+		typename tmat2x3<T, P>::value_type const & s);
 
-	template <typename T> 
-	tmat2x3<T> operator/ (
-		typename tmat2x3<T>::value_type const & s,
-		tmat2x3<T> const & m);
+	template <typename T, precision P>
+	tmat2x3<T, P> operator/ (
+		typename tmat2x3<T, P>::value_type const & s,
+		tmat2x3<T, P> const & m);
 
 	// Unary constant operators
-	template <typename T> 
-	tmat2x3<T> const operator-  (
-		tmat2x3<T> const & m);
+	template <typename T, precision P>
+	tmat2x3<T, P> const operator-  (
+		tmat2x3<T, P> const & m);
 
-	template <typename T> 
-	tmat2x3<T> const operator-- (
-		tmat2x3<T> const & m, 
+	template <typename T, precision P>
+	tmat2x3<T, P> const operator-- (
+		tmat2x3<T, P> const & m,
 		int);
 
-	template <typename T> 
-	tmat2x3<T> const operator++ (
-		tmat2x3<T> const & m, 
+	template <typename T, precision P>
+	tmat2x3<T, P> const operator++ (
+		tmat2x3<T, P> const & m,
 		int);
 }//namespace detail
 }//namespace glm

+ 200 - 200
glm/core/type_mat2x3.inl

@@ -29,20 +29,20 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat2x3<T>::size_type tmat2x3<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat2x3<T, P>::size_type tmat2x3<T, P>::length() const
 	{
 		return 2;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x3<T>::size_type tmat2x3<T>::col_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x3<T, P>::size_type tmat2x3<T, P>::col_size()
 	{
 		return 3;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x3<T>::size_type tmat2x3<T>::row_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x3<T, P>::size_type tmat2x3<T, P>::row_size()
 	{
 		return 2;
 	}
@@ -50,9 +50,9 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x3<T>::col_type &
-	tmat2x3<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x3<T, P>::col_type &
+	tmat2x3<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -61,9 +61,9 @@ namespace detail
 		return this->value[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x3<T>::col_type const &
-	tmat2x3<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x3<T, P>::col_type const &
+	tmat2x3<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -75,32 +75,32 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Constructors
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3()
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3()
 	{
 		this->value[0] = col_type(T(1), T(0), T(0));
 		this->value[1] = col_type(T(0), T(1), T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = m.value[0];
 		this->value[1] = m.value[1];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
 		ctor
 	)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
 		value_type const & s
 	)
@@ -109,8 +109,8 @@ namespace detail
 		this->value[1] = col_type(T(0), s, T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
 		value_type const & x0, value_type const & y0, value_type const & z0,
 		value_type const & x1, value_type const & y1, value_type const & z1
@@ -120,10 +120,10 @@ namespace detail
 		this->value[1] = col_type(x1, y1, z1);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		col_type const & v0, 
+		col_type const & v0,
 		col_type const & v1
 	)
 	{
@@ -133,25 +133,25 @@ namespace detail
 
 	//////////////////////////////////////
 	// Convertion constructors
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_DECL tmat2x3<T>::tmat2x3
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_DECL tmat2x3<T, P>::tmat2x3
 	(
 		U const & s
 	)
 	{
 		value_type const Zero(0);
-		this->value[0] = tvec3<T>(value_type(s), Zero, Zero);
-		this->value[1] = tvec3<T>(Zero, value_type(s), Zero);
+		this->value[0] = tvec3<T, P>(value_type(s), Zero, Zero);
+		this->value[1] = tvec3<T, P>(Zero, value_type(s), Zero);
 	}
 	
-	template <typename T> 
+	template <typename T, precision P>
 	template <
-		typename X1, typename Y1, typename Z1, 
-		typename X2, typename Y2, typename Z2> 
-	GLM_FUNC_DECL tmat2x3<T>::tmat2x3
+		typename X1, typename Y1, typename Z1,
+		typename X2, typename Y2, typename Z2>
+	GLM_FUNC_DECL tmat2x3<T, P>::tmat2x3
 	(
-		X1 const & x1, Y1 const & y1, Z1 const & z1, 
+		X1 const & x1, Y1 const & y1, Z1 const & z1,
 		X2 const & x2, Y2 const & y2, Z2 const & z2
 	)		
 	{
@@ -159,12 +159,12 @@ namespace detail
 		this->value[1] = col_type(value_type(x2), value_type(y2), value_type(z2));
 	}
 	
-	template <typename T> 
-	template <typename V1, typename V2> 
-	GLM_FUNC_DECL tmat2x3<T>::tmat2x3
+	template <typename T, precision P>
+	template <typename V1, typename V2>
+	GLM_FUNC_DECL tmat2x3<T, P>::tmat2x3
 	(
-		tvec3<V1> const & v1, 
-		tvec3<V2> const & v2
+		tvec3<V1, P> const & v1,
+		tvec3<V2, P> const & v2
 	)		
 	{
 		this->value[0] = col_type(v1);
@@ -173,92 +173,92 @@ namespace detail
 
 	//////////////////////////////////////
 	// Matrix conversions
-    
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat2x3<U> const & m
+		tmat2x3<U, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
 		this->value[1] = col_type(m[1], T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
 		this->value[1] = col_type(m[1], T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
 		this->value[1] = col_type(m[1], T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>::tmat2x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>::tmat2x3
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -268,10 +268,10 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Unary updatable operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator= 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>& tmat2x3<T, P>::operator= 
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -279,11 +279,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator= 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>& tmat2x3<T, P>::operator= 
 	(
-		tmat2x3<U> const & m
+		tmat2x3<U, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -291,9 +291,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator+= 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> & tmat2x3<T, P>::operator+= 
 	(
 		U const & s
 	)
@@ -303,11 +303,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator+=
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>& tmat2x3<T, P>::operator+=
 	(
-		tmat2x3<U> const & m
+		tmat2x3<U, P> const & m
 	)
 	{
 		this->value[0] += m[0];
@@ -315,9 +315,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator-= 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>& tmat2x3<T, P>::operator-= 
 	(
 		U const & s
 	)
@@ -327,11 +327,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator-= 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>& tmat2x3<T, P>::operator-= 
 	(
-		tmat2x3<U> const & m
+		tmat2x3<U, P> const & m
 	)
 	{
 		this->value[0] -= m[0];
@@ -339,9 +339,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x3<T>& tmat2x3<T>::operator*= 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P>& tmat2x3<T, P>::operator*= 
 	(
 		U const & s
 	)
@@ -351,19 +351,19 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator*= 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> & tmat2x3<T, P>::operator*= 
 	(
-		tmat2x3<U> const & m
+		tmat2x3<U, P> const & m
 	)
 	{
-		return (*this = tmat2x3<U>(*this * m));
+		return (*this = tmat2x3<U, P>(*this * m));
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator/= 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> & tmat2x3<T, P>::operator/= 
 	(
 		U const & s
 	)
@@ -373,16 +373,16 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator++ ()
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> & tmat2x3<T, P>::operator++ ()
 	{
 		++this->value[0];
 		++this->value[1];
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> & tmat2x3<T>::operator-- ()
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> & tmat2x3<T, P>::operator-- ()
 	{
 		--this->value[0];
 		--this->value[1];
@@ -392,109 +392,109 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Binary operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator+ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator+ 
 	(
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::value_type const & s
+		tmat2x3<T, P> const & m, 
+		typename tmat2x3<T, P>::value_type const & s
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m[0] + s,
 			m[1] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator+ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator+ 
 	(
-		tmat2x3<T> const & m1, 
-		tmat2x3<T> const & m2
+		tmat2x3<T, P> const & m1, 
+		tmat2x3<T, P> const & m2
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m1[0] + m2[0],
 			m1[1] + m2[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator- 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator- 
 	(
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::value_type const & s
+		tmat2x3<T, P> const & m, 
+		typename tmat2x3<T, P>::value_type const & s
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m[0] - s,
 			m[1] - s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator- 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator- 
 	(
-		tmat2x3<T> const & m1, 
-		tmat2x3<T> const & m2
+		tmat2x3<T, P> const & m1, 
+		tmat2x3<T, P> const & m2
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m1[0] - m2[0],
 			m1[1] - m2[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator* 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator* 
 	(
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::value_type const & s
+		tmat2x3<T, P> const & m, 
+		typename tmat2x3<T, P>::value_type const & s
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m[0] * s,
 			m[1] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator*
 	(
-		typename tmat2x3<T>::value_type const & s, 
-		tmat2x3<T> const & m
+		typename tmat2x3<T, P>::value_type const & s,
+		tmat2x3<T, P> const & m
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m[0] * s,
 			m[1] * s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x3<T>::col_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x3<T, P>::col_type operator*
 	(
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::row_type const & v)
+		tmat2x3<T, P> const & m,
+		typename tmat2x3<T, P>::row_type const & v)
 	{
-		return typename tmat2x3<T>::col_type(
+		return typename tmat2x3<T, P>::col_type(
 			m[0][0] * v.x + m[1][0] * v.y,
 			m[0][1] * v.x + m[1][1] * v.y,
 			m[0][2] * v.x + m[1][2] * v.y);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat2x3<T>::row_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x3<T, P>::row_type operator*
 	(
-		typename tmat2x3<T>::col_type const & v, 
-		tmat2x3<T> const & m) 
+		typename tmat2x3<T, P>::col_type const & v,
+		tmat2x3<T, P> const & m)
 	{
-		return typename tmat2x3<T>::row_type(
+		return typename tmat2x3<T, P>::row_type(
 			v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2],
 			v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator*
 	(
-		tmat2x3<T> const & m1, 
-		tmat2x2<T> const & m2
+		tmat2x3<T, P> const & m1,
+		tmat2x2<T, P> const & m2
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
@@ -503,28 +503,28 @@ namespace detail
 			m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator*
 	(
-		tmat2x3<T> const & m1, 
-		tmat3x2<T> const & m2
+		tmat2x3<T, P> const & m1,
+		tmat3x2<T, P> const & m2
 	)
 	{
-		typename tmat2x3<T>::value_type SrcA00 = m1[0][0];
-		typename tmat2x3<T>::value_type SrcA01 = m1[0][1];
-		typename tmat2x3<T>::value_type SrcA02 = m1[0][2];
-		typename tmat2x3<T>::value_type SrcA10 = m1[1][0];
-		typename tmat2x3<T>::value_type SrcA11 = m1[1][1];
-		typename tmat2x3<T>::value_type SrcA12 = m1[1][2];
+		typename tmat2x3<T, P>::value_type SrcA00 = m1[0][0];
+		typename tmat2x3<T, P>::value_type SrcA01 = m1[0][1];
+		typename tmat2x3<T, P>::value_type SrcA02 = m1[0][2];
+		typename tmat2x3<T, P>::value_type SrcA10 = m1[1][0];
+		typename tmat2x3<T, P>::value_type SrcA11 = m1[1][1];
+		typename tmat2x3<T, P>::value_type SrcA12 = m1[1][2];
 
-		typename tmat2x3<T>::value_type SrcB00 = m2[0][0];
-		typename tmat2x3<T>::value_type SrcB01 = m2[0][1];
-		typename tmat2x3<T>::value_type SrcB10 = m2[1][0];
-		typename tmat2x3<T>::value_type SrcB11 = m2[1][1];
-		typename tmat2x3<T>::value_type SrcB20 = m2[2][0];
-		typename tmat2x3<T>::value_type SrcB21 = m2[2][1];
+		typename tmat2x3<T, P>::value_type SrcB00 = m2[0][0];
+		typename tmat2x3<T, P>::value_type SrcB01 = m2[0][1];
+		typename tmat2x3<T, P>::value_type SrcB10 = m2[1][0];
+		typename tmat2x3<T, P>::value_type SrcB11 = m2[1][1];
+		typename tmat2x3<T, P>::value_type SrcB20 = m2[2][0];
+		typename tmat2x3<T, P>::value_type SrcB21 = m2[2][1];
 
-		tmat3x3<T> Result(tmat3x3<T>::null);
+		tmat3x3<T, P> Result(tmat3x3<T, P>::null);
 		Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01;
 		Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01;
 		Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01;
@@ -537,14 +537,14 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator*
 	(
-		tmat2x3<T> const & m1, 
-		tmat4x2<T> const & m2
+		tmat2x3<T, P> const & m1,
+		tmat4x2<T, P> const & m2
 	)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
@@ -559,84 +559,84 @@ namespace detail
 			m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator/
 	(
-		tmat2x3<T> const & m, 
-		typename tmat2x3<T>::value_type const & s
+		tmat2x3<T, P> const & m,
+		typename tmat2x3<T, P>::value_type const & s
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m[0] / s,
 			m[1] / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator/
 	(
-		typename tmat2x3<T>::value_type const & s, 
-		tmat2x3<T> const & m
+		typename tmat2x3<T, P>::value_type const & s,
+		tmat2x3<T, P> const & m
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			s / m[0],
 			s / m[1]);
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> const operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> const operator-
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
-		return tmat2x3<T>(
-			-m[0], 
+		return tmat2x3<T, P>(
+			-m[0],
 			-m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> const operator++ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> const operator++
 	(
-		tmat2x3<T> const & m, 
+		tmat2x3<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat2x3<T>(
-			m[0] + typename tmat2x3<T>::value_type(1),
-			m[1] + typename tmat2x3<T>::value_type(1));
+		return tmat2x3<T, P>(
+			m[0] + typename tmat2x3<T, P>::value_type(1),
+			m[1] + typename tmat2x3<T, P>::value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x3<T> const operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> const operator--
 	(
-		tmat2x3<T> const & m, 
+		tmat2x3<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat2x3<T>(
-			m[0] - typename tmat2x3<T>::value_type(1),
-			m[1] - typename tmat2x3<T>::value_type(1));
+		return tmat2x3<T, P>(
+			m[0] - typename tmat2x3<T, P>::value_type(1),
+			m[1] - typename tmat2x3<T, P>::value_type(1));
 	}
 
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tmat2x3<T> const & m1, 
-		tmat2x3<T> const & m2
+		tmat2x3<T, P> const & m1,
+		tmat2x3<T, P> const & m2
 	)
 	{
 		return (m1[0] == m2[0]) && (m1[1] == m2[1]);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tmat2x3<T> const & m1, 
-		tmat2x3<T> const & m2
+		tmat2x3<T, P> const & m1,
+		tmat2x3<T, P> const & m2
 	)
 	{
 		return (m1[0] != m2[0]) || (m1[1] != m2[1]);

+ 101 - 101
glm/core/type_mat2x4.hpp

@@ -35,16 +35,16 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> 
+	template <typename T, precision P>
 	struct tmat2x4
 	{
 		enum ctor{null};
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec4<T> col_type;
-		typedef tvec2<T> row_type;
-		typedef tmat2x4<T> type;
-		typedef tmat4x2<T> transpose_type;
+		typedef tvec4<T, P> col_type;
+		typedef tvec2<T, P> row_type;
+		typedef tmat2x4<T, P> type;
+		typedef tmat4x2<T, P> transpose_type;
 
 		static GLM_FUNC_DECL size_type col_size();
 		static GLM_FUNC_DECL size_type row_size();
@@ -73,142 +73,142 @@ namespace detail
 
 		//////////////////////////////////////
 		// Conversions
-		template <typename U> 
+		template <typename U>
 		GLM_FUNC_DECL explicit tmat2x4(
 			U const & x);
 			
 		template <
-			typename X1, typename Y1, typename Z1, typename W1, 
-			typename X2, typename Y2, typename Z2, typename W2> 
+			typename X1, typename Y1, typename Z1, typename W1,
+			typename X2, typename Y2, typename Z2, typename W2>
 		GLM_FUNC_DECL explicit tmat2x4(
-			X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1, 
+			X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
 			X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2);
 			
-		template <typename U, typename V> 
+		template <typename U, typename V>
 		GLM_FUNC_DECL explicit tmat2x4(
-			tvec4<U> const & v1, 
-			tvec4<V> const & v2);
+			tvec4<U, P> const & v1,
+			tvec4<V, P> const & v2);
 
 		//////////////////////////////////////
 		// Matrix conversions
 		template <typename U> 
-		GLM_FUNC_DECL explicit tmat2x4(tmat2x4<U> const & m);
+		GLM_FUNC_DECL explicit tmat2x4(tmat2x4<U, P> const & m);
 
-		GLM_FUNC_DECL explicit tmat2x4(tmat2x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x4(tmat3x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x4(tmat4x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x4(tmat2x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x4(tmat3x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x4(tmat3x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x4(tmat4x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat2x4(tmat4x3<T> const & x);
+		GLM_FUNC_DECL explicit tmat2x4(tmat2x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x4(tmat3x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x4(tmat4x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x4(tmat2x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x4(tmat3x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x4(tmat3x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x4(tmat4x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat2x4(tmat4x3<T, P> const & x);
 
 		// Accesses
 		GLM_FUNC_DECL col_type & operator[](size_type i);
 		GLM_FUNC_DECL col_type const & operator[](size_type i) const;
 
 		// Unary updatable operators
-		GLM_FUNC_DECL tmat2x4<T>& operator=  (tmat2x4<T> const & m);
+		GLM_FUNC_DECL tmat2x4<T, P>& operator=  (tmat2x4<T, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x4<T>& operator=  (tmat2x4<U> const & m);
+		GLM_FUNC_DECL tmat2x4<T, P>& operator=  (tmat2x4<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x4<T>& operator+= (U const & s);
+		GLM_FUNC_DECL tmat2x4<T, P>& operator+= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x4<T>& operator+= (tmat2x4<U> const & m);
+		GLM_FUNC_DECL tmat2x4<T, P>& operator+= (tmat2x4<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x4<T>& operator-= (U const & s);
+		GLM_FUNC_DECL tmat2x4<T, P>& operator-= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x4<T>& operator-= (tmat2x4<U> const & m);
+		GLM_FUNC_DECL tmat2x4<T, P>& operator-= (tmat2x4<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x4<T>& operator*= (U const & s);
+		GLM_FUNC_DECL tmat2x4<T, P>& operator*= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x4<T>& operator*= (tmat2x4<U> const & m);
+		GLM_FUNC_DECL tmat2x4<T, P>& operator*= (tmat2x4<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat2x4<T>& operator/= (U const & s);
+		GLM_FUNC_DECL tmat2x4<T, P>& operator/= (U const & s);
 
-		GLM_FUNC_DECL tmat2x4<T>& operator++ ();
-		GLM_FUNC_DECL tmat2x4<T>& operator-- ();
+		GLM_FUNC_DECL tmat2x4<T, P>& operator++ ();
+		GLM_FUNC_DECL tmat2x4<T, P>& operator-- ();
 	};
 
 	// Binary operators
-	template <typename T> 
-	tmat2x4<T> operator+ (
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x4<T> operator+ (
-		tmat2x4<T> const & m1, 
-		tmat2x4<T> const & m2);
-
-	template <typename T> 
-	tmat2x4<T> operator- (
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x4<T> operator- (
-		tmat2x4<T> const & m1, 
-		tmat2x4<T> const & m2);
-
-	template <typename T> 
-	tmat2x4<T> operator* (
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::value_type const & s);
-
-	template <typename T> 
-	tmat2x4<T> operator* (
-		typename tmat2x4<T>::value_type const & s, 
-		tmat2x4<T> const & m);
-
-	template <typename T>
-	typename tmat2x4<T>::col_type operator* (
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::row_type const & v);
-
-	template <typename T> 
-	typename tmat2x4<T>::row_type operator* (
-		typename tmat2x4<T>::col_type const & v, 
-		tmat2x4<T> const & m);
-
-	template <typename T>
-	tmat4x4<T> operator* (
-		tmat2x4<T> const & m1, 
-		tmat4x2<T> const & m2);
+	template <typename T, precision P> 
+	tmat2x4<T, P> operator+ (
+		tmat2x4<T, P> const & m, 
+		typename tmat2x4<T, P>::value_type const & s);
+
+	template <typename T, precision P> 
+	tmat2x4<T, P> operator+ (
+		tmat2x4<T, P> const & m1, 
+		tmat2x4<T, P> const & m2);
+
+	template <typename T, precision P> 
+	tmat2x4<T, P> operator- (
+		tmat2x4<T, P> const & m, 
+		typename tmat2x4<T, P>::value_type const & s);
+
+	template <typename T, precision P> 
+	tmat2x4<T, P> operator- (
+		tmat2x4<T, P> const & m1, 
+		tmat2x4<T, P> const & m2);
+
+	template <typename T, precision P> 
+	tmat2x4<T, P> operator* (
+		tmat2x4<T, P> const & m, 
+		typename tmat2x4<T, P>::value_type const & s);
+
+	template <typename T, precision P> 
+	tmat2x4<T, P> operator* (
+		typename tmat2x4<T, P>::value_type const & s, 
+		tmat2x4<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat2x4<T, P>::col_type operator* (
+		tmat2x4<T, P> const & m, 
+		typename tmat2x4<T, P>::row_type const & v);
+
+	template <typename T, precision P> 
+	typename tmat2x4<T, P>::row_type operator* (
+		typename tmat2x4<T, P>::col_type const & v, 
+		tmat2x4<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator* (
+		tmat2x4<T, P> const & m1, 
+		tmat4x2<T, P> const & m2);
 		
-	template <typename T>
-	tmat2x4<T> operator* (
-		tmat2x4<T> const & m1, 
-		tmat2x2<T> const & m2);
+	template <typename T, precision P>
+	tmat2x4<T, P> operator* (
+		tmat2x4<T, P> const & m1, 
+		tmat2x2<T, P> const & m2);
 		
-	template <typename T>
-	tmat3x4<T> operator* (
-		tmat2x4<T> const & m1, 
-		tmat3x2<T> const & m2);
+	template <typename T, precision P>
+	tmat3x4<T, P> operator* (
+		tmat2x4<T, P> const & m1, 
+		tmat3x2<T, P> const & m2);
 
-	template <typename T> 
-	tmat2x4<T> operator/ (
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::value_type const & s);
+	template <typename T, precision P> 
+	tmat2x4<T, P> operator/ (
+		tmat2x4<T, P> const & m, 
+		typename tmat2x4<T, P>::value_type const & s);
 
-	template <typename T> 
-	tmat2x4<T> operator/ (
-		typename tmat2x4<T>::value_type const & s, 
-		tmat2x4<T> const & m);
+	template <typename T, precision P> 
+	tmat2x4<T, P> operator/ (
+		typename tmat2x4<T, P>::value_type const & s, 
+		tmat2x4<T, P> const & m);
 
 	// Unary constant operators
-	template <typename T> 
-	tmat2x4<T> const operator-  (
-		tmat2x4<T> const & m);
+	template <typename T, precision P> 
+	tmat2x4<T, P> const operator-  (
+		tmat2x4<T, P> const & m);
 
-	template <typename T> 
-	tmat2x4<T> const operator-- (
-		tmat2x4<T> const & m, 
+	template <typename T, precision P> 
+	tmat2x4<T, P> const operator-- (
+		tmat2x4<T, P> const & m, 
 		int);
 
-	template <typename T> 
-	tmat2x4<T> const operator++ (
-		tmat2x4<T> const & m, 
+	template <typename T, precision P> 
+	tmat2x4<T, P> const operator++ (
+		tmat2x4<T, P> const & m, 
 		int);
 
 }//namespace detail

+ 220 - 220
glm/core/type_mat2x4.inl

@@ -29,20 +29,20 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat2x4<T>::size_type tmat2x4<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat2x4<T, P>::size_type tmat2x4<T, P>::length() const
 	{
 		return 2;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x4<T>::size_type tmat2x4<T>::col_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x4<T, P>::size_type tmat2x4<T, P>::col_size()
 	{
 		return 4;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x4<T>::size_type tmat2x4<T>::row_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x4<T, P>::size_type tmat2x4<T, P>::row_size()
 	{
 		return 2;
 	}
@@ -50,9 +50,9 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x4<T>::col_type &
-	tmat2x4<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x4<T, P>::col_type &
+	tmat2x4<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -61,9 +61,9 @@ namespace detail
 		return this->value[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x4<T>::col_type const &
-	tmat2x4<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x4<T, P>::col_type const &
+	tmat2x4<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -75,8 +75,8 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Constructors
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4()
 	{
 		value_type const Zero(0);
 		value_type const One(1);
@@ -84,25 +84,25 @@ namespace detail
 		this->value[1] = col_type(Zero, One, Zero, Zero);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = m.value[0];
 		this->value[1] = m.value[1];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
 		ctor
 	)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
 		value_type const & s
 	)
@@ -112,8 +112,8 @@ namespace detail
 		this->value[1] = col_type(Zero, Zero, Zero, Zero);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
 		value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0,
 		value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1
@@ -123,10 +123,10 @@ namespace detail
 		this->value[1] = col_type(x1, y1, z1, w1);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		col_type const & v0, 
+		col_type const & v0,
 		col_type const & v1
 	)
 	{
@@ -136,38 +136,38 @@ namespace detail
 
 	//////////////////////////////////////
 	// Convertion constructors
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_DECL tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_DECL tmat2x4<T, P>::tmat2x4
 	(
 		U const & s
 	)
 	{
 		value_type const Zero(0);
-		this->value[0] = tvec4<T>(value_type(s), Zero, Zero, Zero);
-		this->value[1] = tvec4<T>(Zero, value_type(s), Zero, Zero);
+		this->value[0] = tvec4<T, P>(value_type(s), Zero, Zero, Zero);
+		this->value[1] = tvec4<T, P>(Zero, value_type(s), Zero, Zero);
 	}
 	
-	template <typename T> 
+	template <typename T, precision P>
 	template <
-		typename X1, typename Y1, typename Z1, typename W1, 
-		typename X2, typename Y2, typename Z2, typename W2> 
-	GLM_FUNC_DECL tmat2x4<T>::tmat2x4
+		typename X1, typename Y1, typename Z1, typename W1,
+		typename X2, typename Y2, typename Z2, typename W2>
+	GLM_FUNC_DECL tmat2x4<T, P>::tmat2x4
 	(
-		X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1, 
-		X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2 
+		X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
+		X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2
 	)		
 	{
 		this->value[0] = col_type(value_type(x1), value_type(y1), value_type(z1), value_type(w1));
 		this->value[1] = col_type(value_type(x2), value_type(y2), value_type(z2), value_type(w2));
 	}
 	
-	template <typename T> 
-	template <typename V1, typename V2> 
-	GLM_FUNC_DECL tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	template <typename V1, typename V2>
+	GLM_FUNC_DECL tmat2x4<T, P>::tmat2x4
 	(
-		tvec4<V1> const & v1, 
-		tvec4<V2> const & v2
+		tvec4<V1, P> const & v1,
+		tvec4<V2, P> const & v2
 	)		
 	{
 		this->value[0] = col_type(v1);
@@ -177,91 +177,91 @@ namespace detail
 	//////////////////////////////////////
 	// Matrix conversions
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat2x4<U> const & m
+		tmat2x4<U, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
-		this->value[0] = col_type(m[0], detail::tvec2<T>(0));
-		this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
+		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
 		this->value[1] = col_type(m[1], T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
 		this->value[1] = col_type(m[1], T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
-		this->value[0] = col_type(m[0], detail::tvec2<T>(0));
-		this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
+		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
 		this->value[1] = m[1];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
-		this->value[0] = col_type(m[0], detail::tvec2<T>(T(0)));
-		this->value[1] = col_type(m[1], detail::tvec2<T>(T(0)));
+		this->value[0] = col_type(m[0], detail::tvec2<T, P>(T(0)));
+		this->value[1] = col_type(m[1], detail::tvec2<T, P>(T(0)));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>::tmat2x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>::tmat2x4
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
@@ -271,10 +271,10 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Unary updatable operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator= 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator=
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -282,11 +282,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator=
 	(
-		tmat2x4<U> const & m
+		tmat2x4<U, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -294,9 +294,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator+=
 	(
 		U const & s
 	)
@@ -306,11 +306,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator+=
 	(
-		tmat2x4<U> const & m
+		tmat2x4<U, P> const & m
 	)
 	{
 		this->value[0] += m[0];
@@ -318,9 +318,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator-=
 	(
 		U const & s
 	)
@@ -330,11 +330,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator-=
 	(
-		tmat2x4<U> const & m
+		tmat2x4<U, P> const & m
 	)
 	{
 		this->value[0] -= m[0];
@@ -342,9 +342,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator*=
 	(
 		U const & s
 	)
@@ -354,19 +354,19 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator*=
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator*=
 	(
-		tmat2x4<U> const & m
+		tmat2x4<U, P> const & m
 	)
 	{
-		return (*this = tmat2x4<T>(*this * m));
+		return (*this = tmat2x4<T, P>(*this * m));
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> & tmat2x4<T>::operator/= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> & tmat2x4<T, P>::operator/=
 	(
 		U const & s
 	)
@@ -376,16 +376,16 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator++ ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator++ ()
 	{
 		++this->value[0];
 		++this->value[1];
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T>& tmat2x4<T>::operator-- ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P>& tmat2x4<T, P>::operator-- ()
 	{
 		--this->value[0];
 		--this->value[1];
@@ -395,130 +395,130 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Binary operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator+
 	(
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::value_type const & s
+		tmat2x4<T, P> const & m,
+		typename tmat2x4<T, P>::value_type const & s
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m[0] + s,
 			m[1] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator+ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator+
 	(
-		tmat2x4<T> const & m1, 
-		tmat2x4<T> const & m2
+		tmat2x4<T, P> const & m1,
+		tmat2x4<T, P> const & m2
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m1[0] + m2[0],
 			m1[1] + m2[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator- 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator-
 	(
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::value_type const & s
+		tmat2x4<T, P> const & m,
+		typename tmat2x4<T, P>::value_type const & s
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m[0] - s,
 			m[1] - s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator-
 	(
-		tmat2x4<T> const & m1, 
-		tmat2x4<T> const & m2
+		tmat2x4<T, P> const & m1,
+		tmat2x4<T, P> const & m2
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m1[0] - m2[0],
 			m1[1] - m2[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator*
 	(
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::value_type const & s
+		tmat2x4<T, P> const & m,
+		typename tmat2x4<T, P>::value_type const & s
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m[0] * s,
 			m[1] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator*
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator*
 	(
-		typename tmat2x4<T>::value_type const & s, 
-		tmat2x4<T> const & m
+		typename tmat2x4<T, P>::value_type const & s, 
+		tmat2x4<T, P> const & m
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m[0] * s,
 			m[1] * s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat2x4<T>::col_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x4<T, P>::col_type operator* 
 	(
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::row_type const & v
+		tmat2x4<T, P> const & m, 
+		typename tmat2x4<T, P>::row_type const & v
 	)
 	{
-		return typename tmat2x4<T>::col_type(
+		return typename tmat2x4<T, P>::col_type(
 			m[0][0] * v.x + m[1][0] * v.y,
 			m[0][1] * v.x + m[1][1] * v.y,
 			m[0][2] * v.x + m[1][2] * v.y,
 			m[0][3] * v.x + m[1][3] * v.y);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat2x4<T>::row_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat2x4<T, P>::row_type operator*
 	(
-		typename tmat2x4<T>::col_type const & v, 
-		tmat2x4<T> const & m
-	) 
+		typename tmat2x4<T, P>::col_type const & v,
+		tmat2x4<T, P> const & m
+	)
 	{
-		return typename tmat2x4<T>::row_type(
+		return typename tmat2x4<T, P>::row_type(
 			v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3],
 			v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator*
 	(
-		tmat2x4<T> const & m1, 
-		tmat4x2<T> const & m2
+		tmat2x4<T, P> const & m1,
+		tmat4x2<T, P> const & m2
 	)
 	{
-		typename tmat2x4<T>::value_type SrcA00 = m1[0][0];
-		typename tmat2x4<T>::value_type SrcA01 = m1[0][1];
-		typename tmat2x4<T>::value_type SrcA02 = m1[0][2];
-		typename tmat2x4<T>::value_type SrcA03 = m1[0][3];
-		typename tmat2x4<T>::value_type SrcA10 = m1[1][0];
-		typename tmat2x4<T>::value_type SrcA11 = m1[1][1];
-		typename tmat2x4<T>::value_type SrcA12 = m1[1][2];
-		typename tmat2x4<T>::value_type SrcA13 = m1[1][3];
+		typename tmat2x4<T, P>::value_type SrcA00 = m1[0][0];
+		typename tmat2x4<T, P>::value_type SrcA01 = m1[0][1];
+		typename tmat2x4<T, P>::value_type SrcA02 = m1[0][2];
+		typename tmat2x4<T, P>::value_type SrcA03 = m1[0][3];
+		typename tmat2x4<T, P>::value_type SrcA10 = m1[1][0];
+		typename tmat2x4<T, P>::value_type SrcA11 = m1[1][1];
+		typename tmat2x4<T, P>::value_type SrcA12 = m1[1][2];
+		typename tmat2x4<T, P>::value_type SrcA13 = m1[1][3];
 
-		typename tmat2x4<T>::value_type SrcB00 = m2[0][0];
-		typename tmat2x4<T>::value_type SrcB01 = m2[0][1];
-		typename tmat2x4<T>::value_type SrcB10 = m2[1][0];
-		typename tmat2x4<T>::value_type SrcB11 = m2[1][1];
-		typename tmat2x4<T>::value_type SrcB20 = m2[2][0];
-		typename tmat2x4<T>::value_type SrcB21 = m2[2][1];
-		typename tmat2x4<T>::value_type SrcB30 = m2[3][0];
-		typename tmat2x4<T>::value_type SrcB31 = m2[3][1];
+		typename tmat2x4<T, P>::value_type SrcB00 = m2[0][0];
+		typename tmat2x4<T, P>::value_type SrcB01 = m2[0][1];
+		typename tmat2x4<T, P>::value_type SrcB10 = m2[1][0];
+		typename tmat2x4<T, P>::value_type SrcB11 = m2[1][1];
+		typename tmat2x4<T, P>::value_type SrcB20 = m2[2][0];
+		typename tmat2x4<T, P>::value_type SrcB21 = m2[2][1];
+		typename tmat2x4<T, P>::value_type SrcB30 = m2[3][0];
+		typename tmat2x4<T, P>::value_type SrcB31 = m2[3][1];
 
-		tmat4x4<T> Result(tmat4x4<T>::null);
+		tmat4x4<T, P> Result(tmat4x4<T, P>::null);
 		Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01;
 		Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01;
 		Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01;
@@ -538,14 +538,14 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator*
 	(
-		tmat2x4<T> const & m1, 
-		tmat2x2<T> const & m2
+		tmat2x4<T, P> const & m1,
+		tmat2x2<T, P> const & m2
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
@@ -556,14 +556,14 @@ namespace detail
 			m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator*
 	(
-		tmat2x4<T> const & m1, 
-		tmat3x2<T> const & m2
+		tmat2x4<T, P> const & m1,
+		tmat3x2<T, P> const & m2
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1],
@@ -578,84 +578,84 @@ namespace detail
 			m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator/ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator/
 	(
-		tmat2x4<T> const & m, 
-		typename tmat2x4<T>::value_type const & s
+		tmat2x4<T, P> const & m,
+		typename tmat2x4<T, P>::value_type const & s
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m[0] / s,
-			m[1] / s);        
+			m[1] / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator/
 	(
-		typename tmat2x4<T>::value_type const & s, 
-		tmat2x4<T> const & m
+		typename tmat2x4<T, P>::value_type const & s,
+		tmat2x4<T, P> const & m
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			s / m[0],
-			s / m[1]);        
+			s / m[1]);
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> const operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> const operator-
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			-m[0], 
 			-m[1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> const operator++ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> const operator++
 	(
-		tmat2x4<T> const & m, 
+		tmat2x4<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat2x4<T>(
-			m[0] + typename tmat2x4<T>::value_type(1),
-			m[1] + typename tmat2x4<T>::value_type(1));
+		return tmat2x4<T, P>(
+			m[0] + typename tmat2x4<T, P>::value_type(1),
+			m[1] + typename tmat2x4<T, P>::value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x4<T> const operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> const operator--
 	(
-		tmat2x4<T> const & m, 
+		tmat2x4<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat2x4<T>(
-			m[0] - typename tmat2x4<T>::value_type(1),
-			m[1] - typename tmat2x4<T>::value_type(1));
+		return tmat2x4<T, P>(
+			m[0] - typename tmat2x4<T, P>::value_type(1),
+			m[1] - typename tmat2x4<T, P>::value_type(1));
 	}
 
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tmat2x4<T> const & m1, 
-		tmat2x4<T> const & m2
+		tmat2x4<T, P> const & m1,
+		tmat2x4<T, P> const & m2
 	)
 	{
 		return (m1[0] == m2[0]) && (m1[1] == m2[1]);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tmat2x4<T> const & m1, 
-		tmat2x4<T> const & m2
+		tmat2x4<T, P> const & m1,
+		tmat2x4<T, P> const & m2
 	)
 	{
 		return (m1[0] != m2[0]) || (m1[1] != m2[1]);

+ 108 - 108
glm/core/type_mat3x2.hpp

@@ -35,16 +35,16 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> 
+	template <typename T, precision P>
 	struct tmat3x2
 	{
 		enum ctor{null};
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec2<T> col_type;
-		typedef tvec3<T> row_type;
-		typedef tmat3x2<T> type;
-		typedef tmat2x3<T> transpose_type;
+		typedef tvec2<T, P> col_type;
+		typedef tvec3<T, P> row_type;
+		typedef tmat3x2<T, P> type;
+		typedef tmat2x3<T, P> transpose_type;
 
 		static GLM_FUNC_DECL size_type col_size();
 		static GLM_FUNC_DECL size_type row_size();
@@ -58,7 +58,7 @@ namespace detail
 	public:
 		// Constructors
 		GLM_FUNC_DECL tmat3x2();
-		GLM_FUNC_DECL tmat3x2(tmat3x2 const & m);
+		GLM_FUNC_DECL tmat3x2(tmat3x2<T, P> const & m);
 
 		GLM_FUNC_DECL explicit tmat3x2(
 			ctor);
@@ -69,152 +69,152 @@ namespace detail
 			value_type const & x1, value_type const & y1,
 			value_type const & x2, value_type const & y2);
 		GLM_FUNC_DECL explicit tmat3x2(
-			col_type const & v0, 
+			col_type const & v0,
 			col_type const & v1,
 			col_type const & v2);
 
 		//////////////////////////////////////
 		// Conversions
-		template <typename U> 
+		template <typename U>
 		GLM_FUNC_DECL explicit tmat3x2(
 			U const & x);
 			
-		template 
+		template
 		<
-			typename X1, typename Y1, 
-			typename X2, typename Y2, 
+			typename X1, typename Y1,
+			typename X2, typename Y2,
 			typename X3, typename Y3
-		> 
+		>
 		GLM_FUNC_DECL explicit tmat3x2(
-			X1 const & x1, Y1 const & y1, 
+			X1 const & x1, Y1 const & y1,
 			X2 const & x2, Y2 const & y2,
 			X3 const & x3, Y3 const & y3);
 			
-		template <typename V1, typename V2, typename V3> 
+		template <typename V1, typename V2, typename V3>
 		GLM_FUNC_DECL explicit tmat3x2(
-			tvec2<V1> const & v1, 
-			tvec2<V2> const & v2,
-			tvec2<V3> const & v3);
+			tvec2<V1, P> const & v1,
+			tvec2<V2, P> const & v2,
+			tvec2<V3, P> const & v3);
 
 		// Matrix conversions
-		template <typename U> 
-		GLM_FUNC_DECL explicit tmat3x2(tmat3x2<U> const & m);
-
-		GLM_FUNC_DECL explicit tmat3x2(tmat2x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x2(tmat3x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x2(tmat4x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x2(tmat2x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x2(tmat2x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x2(tmat3x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x2(tmat4x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x2(tmat4x3<T> const & x);
+		template <typename U>
+		GLM_FUNC_DECL explicit tmat3x2(tmat3x2<U, P> const & m);
+
+		GLM_FUNC_DECL explicit tmat3x2(tmat2x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x2(tmat3x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x2(tmat4x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x2(tmat2x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x2(tmat2x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x2(tmat3x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x2(tmat4x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x2(tmat4x3<T, P> const & x);
 
 		// Accesses
 		GLM_FUNC_DECL col_type & operator[](size_type i);
 		GLM_FUNC_DECL col_type const & operator[](size_type i) const;
 
 		// Unary updatable operators
-		GLM_FUNC_DECL tmat3x2<T> & operator=  (tmat3x2<T> const & m);
+		GLM_FUNC_DECL tmat3x2<T, P> & operator=  (tmat3x2<T, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x2<T> & operator=  (tmat3x2<U> const & m);
+		GLM_FUNC_DECL tmat3x2<T, P> & operator=  (tmat3x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x2<T> & operator+= (U const & s);
+		GLM_FUNC_DECL tmat3x2<T, P> & operator+= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x2<T> & operator+= (tmat3x2<U> const & m);
+		GLM_FUNC_DECL tmat3x2<T, P> & operator+= (tmat3x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x2<T> & operator-= (U const & s);
+		GLM_FUNC_DECL tmat3x2<T, P> & operator-= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x2<T> & operator-= (tmat3x2<U> const & m);
+		GLM_FUNC_DECL tmat3x2<T, P> & operator-= (tmat3x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x2<T> & operator*= (U const & s);
+		GLM_FUNC_DECL tmat3x2<T, P> & operator*= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x2<T> & operator*= (tmat3x2<U> const & m);
+		GLM_FUNC_DECL tmat3x2<T, P> & operator*= (tmat3x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x2<T> & operator/= (U const & s);
+		GLM_FUNC_DECL tmat3x2<T, P> & operator/= (U const & s);
 
-		GLM_FUNC_DECL tmat3x2<T> & operator++ ();
-		GLM_FUNC_DECL tmat3x2<T> & operator-- ();
+		GLM_FUNC_DECL tmat3x2<T, P> & operator++ ();
+		GLM_FUNC_DECL tmat3x2<T, P> & operator-- ();
 	};
 
 	// Binary operators
-	template <typename T> 
-	tmat3x2<T> operator+ (
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat3x2<T> operator+ (
-		tmat3x2<T> const & m1, 
-		tmat3x2<T> const & m2);
-
-	template <typename T> 
-	tmat3x2<T> operator- (
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat3x2<T> operator- (
-		tmat3x2<T> const & m1, 
-		tmat3x2<T> const & m2);
-
-	template <typename T> 
-	tmat3x2<T> operator* (
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat3x2<T> operator* (
-		typename tmat3x2<T>::value_type const & s, 
-		tmat3x2<T> const & m);
-
-	template <typename T>
-	typename tmat3x2<T>::col_type operator* (
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::row_type const & v);
-
-	template <typename T> 
-	typename tmat3x2<T>::row_type operator* (
-		typename tmat3x2<T>::col_type const & v,
-		tmat3x2<T> const & m);
-
-	template <typename T>
-	tmat2x2<T> operator* (
-		tmat3x2<T> const & m1, 
-		tmat2x3<T> const & m2);
+	template <typename T, precision P>
+	tmat3x2<T, P> operator+ (
+		tmat3x2<T, P> const & m,
+		typename tmat3x2<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat3x2<T, P> operator+ (
+		tmat3x2<T, P> const & m1,
+		tmat3x2<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x2<T, P> operator- (
+		tmat3x2<T, P> const & m,
+		typename tmat3x2<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat3x2<T, P> operator- (
+		tmat3x2<T, P> const & m1,
+		tmat3x2<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x2<T, P> operator* (
+		tmat3x2<T, P> const & m,
+		typename tmat3x2<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat3x2<T, P> operator* (
+		typename tmat3x2<T, P>::value_type const & s,
+		tmat3x2<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat3x2<T, P>::col_type operator* (
+		tmat3x2<T, P> const & m,
+		typename tmat3x2<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat3x2<T, P>::row_type operator* (
+		typename tmat3x2<T, P>::col_type const & v,
+		tmat3x2<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat2x2<T, P> operator* (
+		tmat3x2<T, P> const & m1,
+		tmat2x3<T, P> const & m2);
 		
-	template <typename T>
-	tmat3x2<T> operator* (
-		tmat3x2<T> const & m1, 
-		tmat3x3<T> const & m2);
+	template <typename T, precision P>
+	tmat3x2<T, P> operator* (
+		tmat3x2<T, P> const & m1,
+		tmat3x3<T, P> const & m2);
 		
-	template <typename T>
-	tmat4x2<T> operator* (
-		tmat3x2<T> const & m1, 
-		tmat4x3<T> const & m2);
+	template <typename T, precision P>
+	tmat4x2<T, P> operator* (
+		tmat3x2<T, P> const & m1,
+		tmat4x3<T, P> const & m2);
 
-	template <typename T> 
-	tmat3x2<T> operator/ (
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::value_type const & s);
+	template <typename T, precision P>
+	tmat3x2<T, P> operator/ (
+		tmat3x2<T, P> const & m,
+		typename tmat3x2<T, P>::value_type const & s);
 
-	template <typename T> 
-	tmat3x2<T> operator/ (
-		typename tmat3x2<T>::value_type const & s, 
-		tmat3x2<T> const & m);
+	template <typename T, precision P>
+	tmat3x2<T, P> operator/ (
+		typename tmat3x2<T, P>::value_type const & s,
+		tmat3x2<T, P> const & m);
 
 	// Unary constant operators
-	template <typename T> 
-	tmat3x2<T> const operator-  (
-		tmat3x2<T> const & m);
+	template <typename T, precision P>
+	tmat3x2<T, P> const operator-  (
+		tmat3x2<T, P> const & m);
 
-	template <typename T> 
-	tmat3x2<T> const operator-- (
-		tmat3x2<T> const & m, 
+	template <typename T, precision P>
+	tmat3x2<T, P> const operator-- (
+		tmat3x2<T, P> const & m,
 		int);
 
-	template <typename T> 
-	tmat3x2<T> const operator++ (
-		tmat3x2<T> const & m, 
+	template <typename T, precision P>
+	tmat3x2<T, P> const operator++ (
+		tmat3x2<T, P> const & m,
 		int);
 }//namespace detail
 }//namespace glm

+ 200 - 200
glm/core/type_mat3x2.inl

@@ -29,20 +29,20 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat3x2<T>::size_type tmat3x2<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat3x2<T, P>::size_type tmat3x2<T, P>::length() const
 	{
 		return 3;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x2<T>::size_type tmat3x2<T>::col_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x2<T, P>::size_type tmat3x2<T, P>::col_size()
 	{
 		return 2;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x2<T>::size_type tmat3x2<T>::row_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x2<T, P>::size_type tmat3x2<T, P>::row_size()
 	{
 		return 3;
 	}
@@ -50,9 +50,9 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x2<T>::col_type &
-	tmat3x2<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x2<T, P>::col_type &
+	tmat3x2<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -61,9 +61,9 @@ namespace detail
 		return this->value[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x2<T>::col_type const & 
-	tmat3x2<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x2<T, P>::col_type const & 
+	tmat3x2<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -75,18 +75,18 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Constructors
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2()
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2()
 	{
 		this->value[0] = col_type(1, 0);
 		this->value[1] = col_type(0, 1);
 		this->value[2] = col_type(0, 0);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
 		this->value[0] = m.value[0];
@@ -94,15 +94,15 @@ namespace detail
 		this->value[2] = m.value[2];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
 		ctor
 	)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
 		value_type const & s
 	)
@@ -112,8 +112,8 @@ namespace detail
 		this->value[2] = col_type(0, 0);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
 		value_type const & x0, value_type const & y0,
 		value_type const & x1, value_type const & y1,
@@ -125,11 +125,11 @@ namespace detail
 		this->value[2] = col_type(x2, y2);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		col_type const & v0, 
-		col_type const & v1, 
+		col_type const & v0,
+		col_type const & v1,
 		col_type const & v2
 	)
 	{
@@ -140,28 +140,28 @@ namespace detail
 
 	//////////////////////////////////////
 	// Convertion constructors
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_DECL tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_DECL tmat3x2<T, P>::tmat3x2
 	(
 		U const & s
 	)
 	{
 		value_type const Zero(0);
-		this->value[0] = tvec2<T>(value_type(s), Zero);
-		this->value[1] = tvec2<T>(Zero, value_type(s));
-		this->value[2] = tvec2<T>(Zero);
+		this->value[0] = tvec2<T, P>(value_type(s), Zero);
+		this->value[1] = tvec2<T, P>(Zero, value_type(s));
+		this->value[2] = tvec2<T, P>(Zero);
 	}
 	
-	template <typename T> 
+	template <typename T, precision P>
 	template <
-		typename X1, typename Y1, 
-		typename X2, typename Y2, 
-		typename X3, typename Y3> 
-	GLM_FUNC_DECL tmat3x2<T>::tmat3x2
+		typename X1, typename Y1,
+		typename X2, typename Y2,
+		typename X3, typename Y3>
+	GLM_FUNC_DECL tmat3x2<T, P>::tmat3x2
 	(
-		X1 const & x1, Y1 const & y1, 
-		X2 const & x2, Y2 const & y2, 
+		X1 const & x1, Y1 const & y1,
+		X2 const & x2, Y2 const & y2,
 		X3 const & x3, Y3 const & y3
 	)		
 	{
@@ -170,13 +170,13 @@ namespace detail
 		this->value[2] = col_type(value_type(x3), value_type(y3));
 	}
 	
-	template <typename T> 
-	template <typename V1, typename V2, typename V3> 
-	GLM_FUNC_DECL tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	template <typename V1, typename V2, typename V3>
+	GLM_FUNC_DECL tmat3x2<T, P>::tmat3x2
 	(
-		tvec2<V1> const & v1, 
-		tvec2<V2> const & v2, 
-		tvec2<V3> const & v3
+		tvec2<V1, P> const & v1,
+		tvec2<V2, P> const & v2,
+		tvec2<V3, P> const & v3
 	)		
 	{
 		this->value[0] = col_type(v1);
@@ -187,11 +187,11 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// mat3x2 matrix conversions
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat3x2<U> const & m
+		tmat3x2<U, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -199,10 +199,10 @@ namespace detail
 		this->value[2] = col_type(m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -210,10 +210,10 @@ namespace detail
 		this->value[2] = col_type(T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -221,10 +221,10 @@ namespace detail
 		this->value[2] = col_type(m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -232,10 +232,10 @@ namespace detail
 		this->value[2] = col_type(m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -243,10 +243,10 @@ namespace detail
 		this->value[2] = col_type(T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -254,10 +254,10 @@ namespace detail
 		this->value[2] = col_type(T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -265,10 +265,10 @@ namespace detail
 		this->value[2] = col_type(m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -276,10 +276,10 @@ namespace detail
 		this->value[2] = m[2];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>::tmat3x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>::tmat3x2
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -290,10 +290,10 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Unary updatable operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator= 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator= 
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -302,11 +302,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator=
 	(
-		tmat3x2<U> const & m
+		tmat3x2<U, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -315,9 +315,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator+=
 	(
 		U const & s
 	)
@@ -328,11 +328,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator+=
 	(
-		tmat3x2<U> const & m
+		tmat3x2<U, P> const & m
 	)
 	{
 		this->value[0] += m[0];
@@ -341,9 +341,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator-=
 	(
 		U const & s
 	)
@@ -354,11 +354,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator-=
 	(
-		tmat3x2<U> const & m
+		tmat3x2<U, P> const & m
 	)
 	{
 		this->value[0] -= m[0];
@@ -367,9 +367,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator*=
 	(
 		U const & s
 	)
@@ -380,19 +380,19 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator*=
 	(
-		tmat3x2<U> const & m
+		tmat3x2<U, P> const & m
 	)
 	{
-		return (*this = tmat3x2<T>(*this * m));
+		return (*this = tmat3x2<T, P>(*this * m));
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> & tmat3x2<T>::operator/= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> & tmat3x2<T, P>::operator/=
 	(
 		U const & s
 	)
@@ -403,8 +403,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator++ ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator++ ()
 	{
 		++this->value[0];
 		++this->value[1];
@@ -412,8 +412,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T>& tmat3x2<T>::operator-- ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P>& tmat3x2<T, P>::operator-- ()
 	{
 		--this->value[0];
 		--this->value[1];
@@ -424,112 +424,112 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Binary operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator+
 	(
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::value_type const & s
+		tmat3x2<T, P> const & m,
+		typename tmat3x2<T, P>::value_type const & s
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m[0] + s,
 			m[1] + s,
 			m[2] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator+
 	(
-		tmat3x2<T> const & m1, 
-		tmat3x2<T> const & m2
+		tmat3x2<T, P> const & m1,
+		tmat3x2<T, P> const & m2
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m1[0] + m2[0],
 			m1[1] + m2[1],
 			m1[2] + m2[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator-
 	(
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::value_type const & s
+		tmat3x2<T, P> const & m,
+		typename tmat3x2<T, P>::value_type const & s
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m[0] - s,
 			m[1] - s,
 			m[2] - s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator- 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator- 
 	(	
-		tmat3x2<T> const & m1, 
-		tmat3x2<T> const & m2
+		tmat3x2<T, P> const & m1, 
+		tmat3x2<T, P> const & m2
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m1[0] - m2[0],
 			m1[1] - m2[1],
 			m1[2] - m2[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator* 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator* 
 	(
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::value_type const & s
+		tmat3x2<T, P> const & m, 
+		typename tmat3x2<T, P>::value_type const & s
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator* 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator* 
 	(
-		typename tmat3x2<T>::value_type const & s, 
-		tmat3x2<T> const & m
+		typename tmat3x2<T, P>::value_type const & s, 
+		tmat3x2<T, P> const & m
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s);
 	}
    
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x2<T>::col_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x2<T, P>::col_type operator* 
 	(
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::row_type const & v)
+		tmat3x2<T, P> const & m, 
+		typename tmat3x2<T, P>::row_type const & v)
 	{
-		return typename tmat3x2<T>::col_type(
+		return typename tmat3x2<T, P>::col_type(
 			m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
 			m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat3x2<T>::row_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x2<T, P>::row_type operator*
 	(
-		typename tmat3x2<T>::col_type const & v, 
-		tmat3x2<T> const & m) 
+		typename tmat3x2<T, P>::col_type const & v,
+		tmat3x2<T, P> const & m)
 	{
-		return typename tmat3x2<T>::row_type(
+		return typename tmat3x2<T, P>::row_type(
 			v.x * m[0][0] + v.y * m[0][1],
 			v.x * m[1][0] + v.y * m[1][1],
 			v.x * m[2][0] + v.y * m[2][1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator*
 	(
-		tmat3x2<T> const & m1, 
-		tmat2x3<T> const & m2
+		tmat3x2<T, P> const & m1,
+		tmat2x3<T, P> const & m2
 	)
 	{
 		const T SrcA00 = m1[0][0];
@@ -546,7 +546,7 @@ namespace detail
 		const T SrcB11 = m2[1][1];
 		const T SrcB12 = m2[1][2];
 
-		tmat2x2<T> Result(tmat2x2<T>::null);
+		tmat2x2<T, P> Result(tmat2x2<T, P>::null);
 		Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
 		Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
 		Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12;
@@ -554,14 +554,14 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator*
 	(
-		tmat3x2<T> const & m1, 
-		tmat3x3<T> const & m2
+		tmat3x2<T, P> const & m1,
+		tmat3x3<T, P> const & m2
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
 			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
@@ -570,14 +570,14 @@ namespace detail
 			m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator*
 	(
-		tmat3x2<T> const & m1, 
-		tmat4x3<T> const & m2
+		tmat3x2<T, P> const & m1,
+		tmat4x3<T, P> const & m2
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
 			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2],
@@ -588,68 +588,68 @@ namespace detail
 			m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator/
 	(
-		tmat3x2<T> const & m, 
-		typename tmat3x2<T>::value_type const & s
+		tmat3x2<T, P> const & m,
+		typename tmat3x2<T, P>::value_type const & s
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m[0] / s,
 			m[1] / s,
-			m[2] / s);        
+			m[2] / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator/ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator/
 	(
-		typename tmat3x2<T>::value_type const & s, 
-		tmat3x2<T> const & m
+		typename tmat3x2<T, P>::value_type const & s,
+		tmat3x2<T, P> const & m
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			s / m[0],
 			s / m[1],
-			s / m[2]);        
+			s / m[2]);
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> const operator- 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> const operator-
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
-		return tmat3x2<T>(
-			-m[0], 
+		return tmat3x2<T, P>(
+			-m[0],
 			-m[1],
 			-m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> const operator++ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> const operator++
 	(
-		tmat3x2<T> const & m, 
+		tmat3x2<T, P> const & m,
 		int
-	) 
+	)
 	{
-		typename tmat3x2<T>::value_type One(1);
-		return tmat3x2<T>(
+		typename tmat3x2<T, P>::value_type One(1);
+		return tmat3x2<T, P>(
 			m[0] + One,
 			m[1] + One,
 			m[2] + One);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x2<T> const operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> const operator--
 	(
-		tmat3x2<T> const & m, 
+		tmat3x2<T, P> const & m,
 		int
-	) 
+	)
 	{
-		typename tmat3x2<T>::value_type One(1);
-		return tmat3x2<T>(
+		typename tmat3x2<T, P>::value_type One(1);
+		return tmat3x2<T, P>(
 			m[0] - One,
 			m[1] - One,
 			m[2] - One);
@@ -658,21 +658,21 @@ namespace detail
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tmat3x2<T> const & m1, 
-		tmat3x2<T> const & m2
+		tmat3x2<T, P> const & m1,
+		tmat3x2<T, P> const & m2
 	)
 	{
 		return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tmat3x2<T> const & m1, 
-		tmat3x2<T> const & m2
+		tmat3x2<T, P> const & m1, 
+		tmat3x2<T, P> const & m2
 	)
 	{
 		return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);

+ 147 - 147
glm/core/type_mat3x3.hpp

@@ -35,16 +35,16 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> 
+	template <typename T, precision P>
 	struct tmat3x3
 	{
 		enum ctor{null};
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec3<T> col_type;
-		typedef tvec3<T> row_type;
-		typedef tmat3x3<T> type;
-		typedef tmat3x3<T> transpose_type;
+		typedef tvec3<T, P> col_type;
+		typedef tvec3<T, P> row_type;
+		typedef tmat3x3<T, P> type;
+		typedef tmat3x3<T, P> transpose_type;
 
 		static GLM_FUNC_DECL size_type col_size();
 		static GLM_FUNC_DECL size_type row_size();
@@ -54,7 +54,7 @@ namespace detail
 	public:
 		/// Implementation detail
 		/// @cond DETAIL
-		GLM_FUNC_DECL tmat3x3<T> _inverse() const;
+		GLM_FUNC_DECL tmat3x3<T, P> _inverse() const;
 		/// @endcond
 
 	private:
@@ -64,7 +64,7 @@ namespace detail
 	public:
 		// Constructors
 		GLM_FUNC_DECL tmat3x3();
-		GLM_FUNC_DECL tmat3x3(tmat3x3 const & m);
+		GLM_FUNC_DECL tmat3x3(tmat3x3<T, P> const & m);
 
 		GLM_FUNC_DECL explicit tmat3x3(
 			ctor Null);
@@ -75,178 +75,178 @@ namespace detail
 			value_type const & x1, value_type const & y1, value_type const & z1,
 			value_type const & x2, value_type const & y2, value_type const & z2);
 		GLM_FUNC_DECL explicit tmat3x3(
-			col_type const & v0, 
+			col_type const & v0,
 			col_type const & v1,
 			col_type const & v2);
 
 		//////////////////////////////////////
 		// Conversions
-		template <typename U> 
+		template <typename U>
 		GLM_FUNC_DECL explicit tmat3x3(
 			U const & x);
 			
-		template 
+		template
 		<
-			typename X1, typename Y1, typename Z1, 
-			typename X2, typename Y2, typename Z2, 
+			typename X1, typename Y1, typename Z1,
+			typename X2, typename Y2, typename Z2,
 			typename X3, typename Y3, typename Z3
-		> 
+		>
 		GLM_FUNC_DECL explicit tmat3x3(
-			X1 const & x1, Y1 const & y1, Z1 const & z1, 
-			X2 const & x2, Y2 const & y2, Z2 const & z2, 
+			X1 const & x1, Y1 const & y1, Z1 const & z1,
+			X2 const & x2, Y2 const & y2, Z2 const & z2,
 			X3 const & x3, Y3 const & y3, Z3 const & z3);
 			
-		template <typename V1, typename V2, typename V3> 
+		template <typename V1, typename V2, typename V3>
 		GLM_FUNC_DECL explicit tmat3x3(
-			tvec3<V1> const & v1, 
-			tvec3<V2> const & v2,
-			tvec3<V3> const & v3);
+			tvec3<V1, P> const & v1,
+			tvec3<V2, P> const & v2,
+			tvec3<V3, P> const & v3);
 
 		// Matrix conversions
-		template <typename U> 
-		GLM_FUNC_DECL explicit tmat3x3(tmat3x3<U> const & m);
-
-		GLM_FUNC_DECL explicit tmat3x3(tmat2x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x3(tmat4x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x3(tmat2x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x3(tmat3x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x3(tmat2x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x3(tmat4x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x3(tmat3x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x3(tmat4x3<T> const & x);
+		template <typename U>
+		GLM_FUNC_DECL explicit tmat3x3(tmat3x3<U, P> const & m);
+
+		GLM_FUNC_DECL explicit tmat3x3(tmat2x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x3(tmat4x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x3(tmat2x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x3(tmat3x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x3(tmat2x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x3(tmat4x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x3(tmat3x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x3(tmat4x3<T, P> const & x);
 
 		// Accesses
 		GLM_FUNC_DECL col_type & operator[](size_type i);
 		GLM_FUNC_DECL col_type const & operator[](size_type i) const;
 
 		// Unary updatable operators
-		GLM_FUNC_DECL tmat3x3<T>& operator=  (tmat3x3<T> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat3x3<T>& operator=  (tmat3x3<U> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat3x3<T>& operator+= (U const & s);
-		template <typename U> 
-		GLM_FUNC_DECL tmat3x3<T>& operator+= (tmat3x3<U> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat3x3<T>& operator-= (U const & s);
-		template <typename U> 
-		GLM_FUNC_DECL tmat3x3<T>& operator-= (tmat3x3<U> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat3x3<T>& operator*= (U const & s);
-		template <typename U> 
-		GLM_FUNC_DECL tmat3x3<T>& operator*= (tmat3x3<U> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat3x3<T>& operator/= (U const & s);
-		template <typename U> 
-		GLM_FUNC_DECL tmat3x3<T>& operator/= (tmat3x3<U> const & m);
-		GLM_FUNC_DECL tmat3x3<T>& operator++ ();
-		GLM_FUNC_DECL tmat3x3<T>& operator-- ();
+		GLM_FUNC_DECL tmat3x3<T, P>& operator=  (tmat3x3<T, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat3x3<T, P>& operator=  (tmat3x3<U, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat3x3<T, P>& operator+= (U const & s);
+		template <typename U>
+		GLM_FUNC_DECL tmat3x3<T, P>& operator+= (tmat3x3<U, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat3x3<T, P>& operator-= (U const & s);
+		template <typename U>
+		GLM_FUNC_DECL tmat3x3<T, P>& operator-= (tmat3x3<U, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat3x3<T, P>& operator*= (U const & s);
+		template <typename U>
+		GLM_FUNC_DECL tmat3x3<T, P>& operator*= (tmat3x3<U, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat3x3<T, P>& operator/= (U const & s);
+		template <typename U>
+		GLM_FUNC_DECL tmat3x3<T, P>& operator/= (tmat3x3<U, P> const & m);
+		GLM_FUNC_DECL tmat3x3<T, P>& operator++ ();
+		GLM_FUNC_DECL tmat3x3<T, P>& operator-- ();
 	};
 
 	// Binary operators
-	template <typename T> 
-	tmat3x3<T> operator+ (
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::value_type const & s);
-
-	template <typename T> 
-	tmat3x3<T> operator+ (
-		typename tmat3x3<T>::value_type const & s, 
-		tmat3x3<T> const & m);
-
-	template <typename T> 
-	tmat3x3<T> operator+ (
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2);
-
-	template <typename T> 
-	tmat3x3<T> operator- (
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::value_type const & s);
-
-	template <typename T> 
-	tmat3x3<T> operator- (
-		typename tmat3x3<T>::value_type const & s, 
-		tmat3x3<T> const & m);
-
-	template <typename T> 
-	tmat3x3<T> operator- (
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2);
-
-	template <typename T> 
-	tmat3x3<T> operator* (
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::value_type const & s);
-
-	template <typename T> 
-	tmat3x3<T> operator* (
-		typename tmat3x3<T>::value_type const & s, 
-		tmat3x3<T> const & m);
-
-	template <typename T> 
-	typename tmat3x3<T>::col_type operator* (
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::row_type const & v);
-
-	template <typename T> 
-	typename tmat3x3<T>::row_type operator* (
-		typename tmat3x3<T>::col_type const & v, 
-		tmat3x3<T> const & m);
-
-	template <typename T> 
-	tmat3x3<T> operator* (
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2);
+	template <typename T, precision P>
+	tmat3x3<T, P> operator+ (
+		tmat3x3<T, P> const & m,
+		typename tmat3x3<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator+ (
+		typename tmat3x3<T, P>::value_type const & s,
+		tmat3x3<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator+ (
+		tmat3x3<T, P> const & m1,
+		tmat3x3<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator- (
+		tmat3x3<T, P> const & m,
+		typename tmat3x3<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator- (
+		typename tmat3x3<T, P>::value_type const & s,
+		tmat3x3<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator- (
+		tmat3x3<T, P> const & m1,
+		tmat3x3<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator* (
+		tmat3x3<T, P> const & m,
+		typename tmat3x3<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator* (
+		typename tmat3x3<T, P>::value_type const & s,
+		tmat3x3<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat3x3<T, P>::col_type operator* (
+		tmat3x3<T, P> const & m,
+		typename tmat3x3<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat3x3<T, P>::row_type operator* (
+		typename tmat3x3<T, P>::col_type const & v,
+		tmat3x3<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator* (
+		tmat3x3<T, P> const & m1,
+		tmat3x3<T, P> const & m2);
 		
-	template <typename T>
-	tmat2x3<T> operator* (
-		tmat3x3<T> const & m1, 
-		tmat2x3<T> const & m2);
+	template <typename T, precision P>
+	tmat2x3<T, P> operator* (
+		tmat3x3<T, P> const & m1,
+		tmat2x3<T, P> const & m2);
 		
-	template <typename T>
-	tmat4x3<T> operator* (
-		tmat3x3<T> const & m1, 
-		tmat4x3<T> const & m2);
-
-	template <typename T> 
-	tmat3x3<T> operator/ (
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::value_type const & s);
-
-	template <typename T> 
-	tmat3x3<T> operator/ (
-		typename tmat3x3<T>::value_type const & s, 
-		tmat3x3<T> const & m);
-
-	template <typename T> 
-	typename tmat3x3<T>::col_type operator/ (
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::row_type const & v);
-
-	template <typename T> 
-	typename tmat3x3<T>::row_type operator/ (
-		typename tmat3x3<T>::col_type const & v, 
-		tmat3x3<T> const & m);
-
-	template <typename T> 
-	tmat3x3<T> operator/ (
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2);
+	template <typename T, precision P>
+	tmat4x3<T, P> operator* (
+		tmat3x3<T, P> const & m1,
+		tmat4x3<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator/ (
+		tmat3x3<T, P> const & m,
+		typename tmat3x3<T, P>::value_type const & s);
+
+	template <typename T, precision P> 
+	tmat3x3<T, P> operator/ (
+		typename tmat3x3<T, P>::value_type const & s,
+		tmat3x3<T, P> const & m);
+
+	template <typename T, precision P> 
+	typename tmat3x3<T, P>::col_type operator/ (
+		tmat3x3<T, P> const & m, 
+		typename tmat3x3<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat3x3<T, P>::row_type operator/ (
+		typename tmat3x3<T, P>::col_type const & v,
+		tmat3x3<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator/ (
+		tmat3x3<T, P> const & m1,
+		tmat3x3<T, P> const & m2);
 
 	// Unary constant operators
-	template <typename T> 
-	tmat3x3<T> const operator-  (
-		tmat3x3<T> const & m);
+	template <typename T, precision P>
+	tmat3x3<T, P> const operator-  (
+		tmat3x3<T, P> const & m);
 
-	template <typename T> 
-	tmat3x3<T> const operator-- (
-		tmat3x3<T> const & m, 
+	template <typename T, precision P>
+	tmat3x3<T, P> const operator-- (
+		tmat3x3<T, P> const & m,
 		int);
 
-	template <typename T> 
-	tmat3x3<T> const operator++ (
-		tmat3x3<T> const & m, 
+	template <typename T, precision P>
+	tmat3x3<T, P> const operator++ (
+		tmat3x3<T, P> const & m,
 		int);
 }//namespace detail
 }//namespace glm

+ 247 - 247
glm/core/type_mat3x3.inl

@@ -29,20 +29,20 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat3x3<T>::size_type tmat3x3<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat3x3<T, P>::size_type tmat3x3<T, P>::length() const
 	{
 		return 3;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x3<T>::size_type tmat3x3<T>::col_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::size_type tmat3x3<T, P>::col_size()
 	{
 		return 3;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x3<T>::size_type tmat3x3<T>::row_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::size_type tmat3x3<T, P>::row_size()
 	{
 		return 3;
 	}
@@ -50,9 +50,9 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x3<T>::col_type &
-	tmat3x3<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::col_type &
+	tmat3x3<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -61,9 +61,9 @@ namespace detail
 		return this->value[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x3<T>::col_type const &
-	tmat3x3<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::col_type const &
+	tmat3x3<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -75,8 +75,8 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Constructors
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3()
 	{
 		value_type const Zero(0);
 		value_type const One(1);
@@ -85,10 +85,10 @@ namespace detail
 		this->value[2] = col_type(Zero, Zero, One);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = m.value[0];
@@ -96,15 +96,15 @@ namespace detail
 		this->value[2] = m.value[2];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
 		ctor
 	)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
 		value_type const & s
 	)
@@ -115,10 +115,10 @@ namespace detail
 		this->value[2] = col_type(Zero, Zero, s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		value_type const & x0, value_type const & y0, value_type const & z0, 
+		value_type const & x0, value_type const & y0, value_type const & z0,
 		value_type const & x1, value_type const & y1, value_type const & z1,
 		value_type const & x2, value_type const & y2, value_type const & z2
 	)
@@ -128,11 +128,11 @@ namespace detail
 		this->value[2] = col_type(x2, y2, z2);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		col_type const & v0, 
-		col_type const & v1, 
+		col_type const & v0,
+		col_type const & v1,
 		col_type const & v2
 	)
 	{
@@ -143,29 +143,29 @@ namespace detail
 
 	//////////////////////////////////////
 	// Convertion constructors
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_DECL tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_DECL tmat3x3<T, P>::tmat3x3
 	(
 		U const & s
 	)
 	{
 		value_type const Zero(0);
-		this->value[0] = tvec3<T>(value_type(s), Zero, Zero);
-		this->value[1] = tvec3<T>(Zero, value_type(s), Zero);
-		this->value[2] = tvec3<T>(Zero, Zero, value_type(s));
+		this->value[0] = tvec3<T, P>(value_type(s), Zero, Zero);
+		this->value[1] = tvec3<T, P>(Zero, value_type(s), Zero);
+		this->value[2] = tvec3<T, P>(Zero, Zero, value_type(s));
 	}
 	
-	template <typename T> 
+	template <typename T, precision P>
 	template <
-		typename X1, typename Y1, typename Z1, 
-		typename X2, typename Y2, typename Z2, 
-		typename X3, typename Y3, typename Z3>  
-	GLM_FUNC_DECL tmat3x3<T>::tmat3x3
+		typename X1, typename Y1, typename Z1,
+		typename X2, typename Y2, typename Z2,
+		typename X3, typename Y3, typename Z3>
+	GLM_FUNC_DECL tmat3x3<T, P>::tmat3x3
 	(
-		X1 const & x1, Y1 const & y1, Z1 const & z1, 
-		X2 const & x2, Y2 const & y2, Z2 const & z2, 
-		X3 const & x3, Y3 const & y3, Z3 const & z3 
+		X1 const & x1, Y1 const & y1, Z1 const & z1,
+		X2 const & x2, Y2 const & y2, Z2 const & z2,
+		X3 const & x3, Y3 const & y3, Z3 const & z3
 	)
 	{
 		this->value[0] = col_type(value_type(x1), value_type(y1), value_type(z1));
@@ -173,13 +173,13 @@ namespace detail
 		this->value[2] = col_type(value_type(x3), value_type(y3), value_type(z3));
 	}
 	
-	template <typename T> 
-	template <typename V1, typename V2, typename V3> 
-	GLM_FUNC_DECL tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	template <typename V1, typename V2, typename V3>
+	GLM_FUNC_DECL tmat3x3<T, P>::tmat3x3
 	(
-		tvec3<V1> const & v1, 
-		tvec3<V2> const & v2, 
-		tvec3<V3> const & v3
+		tvec3<V1, P> const & v1,
+		tvec3<V2, P> const & v2,
+		tvec3<V3, P> const & v3
 	)
 	{
 		this->value[0] = col_type(v1);
@@ -190,11 +190,11 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Conversions
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat3x3<U> const & m
+		tmat3x3<U, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -202,21 +202,21 @@ namespace detail
 		this->value[2] = col_type(m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], value_type(0));
 		this->value[1] = col_type(m[1], value_type(0));
-		this->value[2] = col_type(detail::tvec2<T>(0), value_type(1));
+		this->value[2] = col_type(detail::tvec2<T, P>(0), value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -224,21 +224,21 @@ namespace detail
 		this->value[2] = col_type(m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
 		this->value[1] = m[1];
-		this->value[2] = col_type(detail::tvec2<T>(0), value_type(1));
+		this->value[2] = col_type(detail::tvec2<T, P>(0), value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], value_type(0));
@@ -246,21 +246,21 @@ namespace detail
 		this->value[2] = col_type(m[2], value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
 		this->value[1] = col_type(m[1]);
-		this->value[2] = col_type(detail::tvec2<T>(0), value_type(1));
+		this->value[2] = col_type(detail::tvec2<T, P>(0), value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], value_type(0));
@@ -268,10 +268,10 @@ namespace detail
 		this->value[2] = col_type(m[2], value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -279,10 +279,10 @@ namespace detail
 		this->value[2] = col_type(m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T>::tmat3x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P>::tmat3x3
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -293,10 +293,10 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator=
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator=
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -305,11 +305,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator=
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator=
 	(
-		tmat3x3<U> const & m
+		tmat3x3<U, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -318,9 +318,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator+=
 	(
 		U const & s
 	)
@@ -331,11 +331,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator+=
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator+=
 	(
-		tmat3x3<U> const & m
+		tmat3x3<U, P> const & m
 	)
 	{
 		this->value[0] += m[0];
@@ -344,9 +344,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator-=
 	(
 		U const & s
 	)
@@ -357,11 +357,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator-=
 	(
-		tmat3x3<U> const & m
+		tmat3x3<U, P> const & m
 	)
 	{
 		this->value[0] -= m[0];
@@ -370,9 +370,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator*=
 	(
 		U const & s
 	)
@@ -383,19 +383,19 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator*=
 	(
-		tmat3x3<U> const & m
+		tmat3x3<U, P> const & m
 	)
 	{
 		return (*this = *this * m);
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator/= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator/=
 	(
 		U const & s
 	)
@@ -406,18 +406,18 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator/= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator/=
 	(
-		tmat3x3<U> const & m
+		tmat3x3<U, P> const & m
 	)
 	{
 		return (*this = *this / m);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator++ ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator++ ()
 	{
 		++this->value[0];
 		++this->value[1];
@@ -425,8 +425,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> & tmat3x3<T>::operator-- ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> & tmat3x3<T, P>::operator-- ()
 	{
 		--this->value[0];
 		--this->value[1];
@@ -434,8 +434,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> tmat3x3<T>::_inverse() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> tmat3x3<T, P>::_inverse() const
 	{
 		T S00 = value[0][0];
 		T S01 = value[0][1];
@@ -449,7 +449,7 @@ namespace detail
 		T S21 = value[2][1];
 		T S22 = value[2][2];
 /*
-		tmat3x3<T> Inverse(
+		tmat3x3<T, P> Inverse(
 			+ (S11 * S22 - S21 * S12),
 			- (S10 * S22 - S20 * S12),
 			+ (S10 * S21 - S20 * S11),
@@ -460,7 +460,7 @@ namespace detail
 			- (S00 * S12 - S10 * S02),
 			+ (S00 * S11 - S10 * S01));
 */
-		tmat3x3<T> Inverse(
+		tmat3x3<T, P> Inverse(
 			S11 * S22 - S21 * S12,
 			S12 * S20 - S22 * S10,
 			S10 * S21 - S20 * S11,
@@ -482,164 +482,164 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Binary operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator+ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator+ 
 	(
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::value_type const & s
+		tmat3x3<T, P> const & m, 
+		typename tmat3x3<T, P>::value_type const & s
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m[0] + s,
 			m[1] + s,
 			m[2] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator+ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator+ 
 	(
-		typename tmat3x3<T>::value_type const & s, 
-		tmat3x3<T> const & m
+		typename tmat3x3<T, P>::value_type const & s, 
+		tmat3x3<T, P> const & m
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m[0] + s,
 			m[1] + s,
 			m[2] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator+ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator+ 
 	(
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2
+		tmat3x3<T, P> const & m1, 
+		tmat3x3<T, P> const & m2
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m1[0] + m2[0],
 			m1[1] + m2[1],
 			m1[2] + m2[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator- 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator- 
 	(
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::value_type const & s
+		tmat3x3<T, P> const & m, 
+		typename tmat3x3<T, P>::value_type const & s
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m[0] - s,
 			m[1] - s,
 			m[2] - s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator- 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator- 
 	(
-		typename tmat3x3<T>::value_type const & s, 
-		tmat3x3<T> const & m
+		typename tmat3x3<T, P>::value_type const & s, 
+		tmat3x3<T, P> const & m
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			s - m[0],
 			s - m[1],
 			s - m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator- 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator- 
 	(
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2
+		tmat3x3<T, P> const & m1, 
+		tmat3x3<T, P> const & m2
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m1[0] - m2[0],
 			m1[1] - m2[1],
 			m1[2] - m2[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator* 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator* 
 	(
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::value_type const & s
+		tmat3x3<T, P> const & m, 
+		typename tmat3x3<T, P>::value_type const & s
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator* 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator* 
 	(
-		typename tmat3x3<T>::value_type const & s, 
-		tmat3x3<T> const & m
+		typename tmat3x3<T, P>::value_type const & s, 
+		tmat3x3<T, P> const & m
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat3x3<T>::col_type operator* 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::col_type operator* 
 	(
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::row_type const & v
+		tmat3x3<T, P> const & m, 
+		typename tmat3x3<T, P>::row_type const & v
 	)
 	{
-		return typename tmat3x3<T>::col_type(
+		return typename tmat3x3<T, P>::col_type(
 			m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
 			m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
 			m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat3x3<T>::row_type operator* 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::row_type operator* 
 	(
-		typename tmat3x3<T>::col_type const & v, 
-		tmat3x3<T> const & m
+		typename tmat3x3<T, P>::col_type const & v, 
+		tmat3x3<T, P> const & m
 	)
 	{
-		return typename tmat3x3<T>::row_type(
+		return typename tmat3x3<T, P>::row_type(
 			m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z,
 			m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z,
 			m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator* 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator* 
 	(
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2
+		tmat3x3<T, P> const & m1, 
+		tmat3x3<T, P> const & m2
 	)
 	{
-		typename tmat3x3<T>::value_type const SrcA00 = m1[0][0];
-		typename tmat3x3<T>::value_type const SrcA01 = m1[0][1];
-		typename tmat3x3<T>::value_type const SrcA02 = m1[0][2];
-		typename tmat3x3<T>::value_type const SrcA10 = m1[1][0];
-		typename tmat3x3<T>::value_type const SrcA11 = m1[1][1];
-		typename tmat3x3<T>::value_type const SrcA12 = m1[1][2];
-		typename tmat3x3<T>::value_type const SrcA20 = m1[2][0];
-		typename tmat3x3<T>::value_type const SrcA21 = m1[2][1];
-		typename tmat3x3<T>::value_type const SrcA22 = m1[2][2];
+		typename tmat3x3<T, P>::value_type const SrcA00 = m1[0][0];
+		typename tmat3x3<T, P>::value_type const SrcA01 = m1[0][1];
+		typename tmat3x3<T, P>::value_type const SrcA02 = m1[0][2];
+		typename tmat3x3<T, P>::value_type const SrcA10 = m1[1][0];
+		typename tmat3x3<T, P>::value_type const SrcA11 = m1[1][1];
+		typename tmat3x3<T, P>::value_type const SrcA12 = m1[1][2];
+		typename tmat3x3<T, P>::value_type const SrcA20 = m1[2][0];
+		typename tmat3x3<T, P>::value_type const SrcA21 = m1[2][1];
+		typename tmat3x3<T, P>::value_type const SrcA22 = m1[2][2];
 
-		typename tmat3x3<T>::value_type const SrcB00 = m2[0][0];
-		typename tmat3x3<T>::value_type const SrcB01 = m2[0][1];
-		typename tmat3x3<T>::value_type const SrcB02 = m2[0][2];
-		typename tmat3x3<T>::value_type const SrcB10 = m2[1][0];
-		typename tmat3x3<T>::value_type const SrcB11 = m2[1][1];
-		typename tmat3x3<T>::value_type const SrcB12 = m2[1][2];
-		typename tmat3x3<T>::value_type const SrcB20 = m2[2][0];
-		typename tmat3x3<T>::value_type const SrcB21 = m2[2][1];
-		typename tmat3x3<T>::value_type const SrcB22 = m2[2][2];
+		typename tmat3x3<T, P>::value_type const SrcB00 = m2[0][0];
+		typename tmat3x3<T, P>::value_type const SrcB01 = m2[0][1];
+		typename tmat3x3<T, P>::value_type const SrcB02 = m2[0][2];
+		typename tmat3x3<T, P>::value_type const SrcB10 = m2[1][0];
+		typename tmat3x3<T, P>::value_type const SrcB11 = m2[1][1];
+		typename tmat3x3<T, P>::value_type const SrcB12 = m2[1][2];
+		typename tmat3x3<T, P>::value_type const SrcB20 = m2[2][0];
+		typename tmat3x3<T, P>::value_type const SrcB21 = m2[2][1];
+		typename tmat3x3<T, P>::value_type const SrcB22 = m2[2][2];
 
-		tmat3x3<T> Result(tmat3x3<T>::null);
+		tmat3x3<T, P> Result(tmat3x3<T, P>::null);
 		Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
 		Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
 		Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02;
@@ -652,14 +652,14 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator*
 	(
-		tmat3x3<T> const & m1, 
-		tmat2x3<T> const & m2
+		tmat3x3<T, P> const & m1,
+		tmat2x3<T, P> const & m2
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
@@ -668,14 +668,14 @@ namespace detail
 			m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator*
 	(
-		tmat3x3<T> const & m1, 
-		tmat4x3<T> const & m2
+		tmat3x3<T, P> const & m1,
+		tmat4x3<T, P> const & m2
 	)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
@@ -690,96 +690,96 @@ namespace detail
 			m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1] + m1[2][2] * m2[3][2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator/
 	(
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::value_type const & s
+		tmat3x3<T, P> const & m,
+		typename tmat3x3<T, P>::value_type const & s
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m[0] / s,
 			m[1] / s,
 			m[2] / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator/
 	(
-		typename tmat3x3<T>::value_type const & s, 
-		tmat3x3<T> const & m
+		typename tmat3x3<T, P>::value_type const & s,
+		tmat3x3<T, P> const & m
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			s / m[0],
 			s / m[1],
 			s / m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat3x3<T>::col_type operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::col_type operator/
 	(
-		tmat3x3<T> const & m, 
-		typename tmat3x3<T>::row_type const & v
+		tmat3x3<T, P> const & m,
+		typename tmat3x3<T, P>::row_type const & v
 	)
 	{
 		return m._inverse() * v;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat3x3<T>::row_type operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x3<T, P>::row_type operator/
 	(
-		typename tmat3x3<T>::col_type const & v, 
-		tmat3x3<T> const & m
+		typename tmat3x3<T, P>::col_type const & v,
+		tmat3x3<T, P> const & m
 	)
 	{
 		return v * m._inverse();
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator/
 	(
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2
+		tmat3x3<T, P> const & m1,
+		tmat3x3<T, P> const & m2
 	)
 	{
 		return m1 * m2._inverse();
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> const operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> const operator-
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			-m[0], 
 			-m[1],
 			-m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> const operator++ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> const operator++
 	(
-		tmat3x3<T> const & m, 
+		tmat3x3<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m[0] + T(1),
 			m[1] + T(1),
 			m[2] + T(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> const operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> const operator--
 	(
-		tmat3x3<T> const & m, 
+		tmat3x3<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat3x3<T>(
+		return tmat3x3<T, P>(
 			m[0] - T(1),
 			m[1] - T(1),
 			m[2] - T(1));
@@ -788,21 +788,21 @@ namespace detail
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2
+		tmat3x3<T, P> const & m1,
+		tmat3x3<T, P> const & m2
 	)
 	{
 		return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tmat3x3<T> const & m1, 
-		tmat3x3<T> const & m2
+		tmat3x3<T, P> const & m1,
+		tmat3x3<T, P> const & m2
 	)
 	{
 		return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);

+ 102 - 102
glm/core/type_mat3x4.hpp

@@ -35,16 +35,16 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> 
+	template <typename T, precision P>
 	struct tmat3x4
 	{
 		enum ctor{null};
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec4<T> col_type;
-		typedef tvec3<T> row_type;
-		typedef tmat3x4<T> type;
-		typedef tmat4x3<T> transpose_type;
+		typedef tvec4<T, P> col_type;
+		typedef tvec3<T, P> row_type;
+		typedef tmat3x4<T, P> type;
+		typedef tmat4x3<T, P> transpose_type;
 
 		static GLM_FUNC_DECL size_type col_size();
 		static GLM_FUNC_DECL size_type row_size();
@@ -69,17 +69,17 @@ namespace detail
 			value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1,
 			value_type const & x2, value_type const & y2, value_type const & z2, value_type const & w2);
 		GLM_FUNC_DECL explicit tmat3x4(
-			col_type const & v0, 
+			col_type const & v0,
 			col_type const & v1,
 			col_type const & v2);
 
 		//////////////////////////////////////
 		// Conversions
-		template <typename U> 
+		template <typename U>
 		GLM_FUNC_DECL explicit tmat3x4(
 			U const & x);
 			
-		template 
+		template
 		<
 			typename X1, typename Y1, typename Z1, typename W1,
 			typename X2, typename Y2, typename Z2, typename W2,
@@ -92,129 +92,129 @@ namespace detail
 			
 		template <typename V1, typename V2, typename V3>
 		GLM_FUNC_DECL explicit tmat3x4(
-			tvec4<V1> const & v1,
-			tvec4<V2> const & v2,
-			tvec4<V3> const & v3);
+			tvec4<V1, P> const & v1,
+			tvec4<V2, P> const & v2,
+			tvec4<V3, P> const & v3);
 
 		// Matrix conversion
-		template <typename U> 
-		GLM_FUNC_DECL explicit tmat3x4(tmat3x4<U> const & m);
-
-		GLM_FUNC_DECL explicit tmat3x4(tmat2x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x4(tmat3x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x4(tmat4x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x4(tmat2x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x4(tmat3x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x4(tmat2x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x4(tmat4x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat3x4(tmat4x3<T> const & x);
+		template <typename U>
+		GLM_FUNC_DECL explicit tmat3x4(tmat3x4<U, P> const & m);
+
+		GLM_FUNC_DECL explicit tmat3x4(tmat2x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x4(tmat3x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x4(tmat4x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x4(tmat2x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x4(tmat3x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x4(tmat2x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x4(tmat4x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat3x4(tmat4x3<T, P> const & x);
 
 		// Accesses
 		col_type & operator[](size_type i);
 		col_type const & operator[](size_type i) const;
 
 		// Unary updatable operators
-		GLM_FUNC_DECL tmat3x4<T> & operator=  (tmat3x4<T> const & m);
+		GLM_FUNC_DECL tmat3x4<T, P> & operator=  (tmat3x4<T, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x4<T> & operator=  (tmat3x4<U> const & m);
+		GLM_FUNC_DECL tmat3x4<T, P> & operator=  (tmat3x4<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x4<T> & operator+= (U const & s);
+		GLM_FUNC_DECL tmat3x4<T, P> & operator+= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x4<T> & operator+= (tmat3x4<U> const & m);
+		GLM_FUNC_DECL tmat3x4<T, P> & operator+= (tmat3x4<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x4<T> & operator-= (U const & s);
+		GLM_FUNC_DECL tmat3x4<T, P> & operator-= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x4<T> & operator-= (tmat3x4<U> const & m);
+		GLM_FUNC_DECL tmat3x4<T, P> & operator-= (tmat3x4<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x4<T> & operator*= (U const & s);
+		GLM_FUNC_DECL tmat3x4<T, P> & operator*= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x4<T> & operator*= (tmat3x4<U> const & m);
+		GLM_FUNC_DECL tmat3x4<T, P> & operator*= (tmat3x4<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat3x4<T> & operator/= (U const & s);
+		GLM_FUNC_DECL tmat3x4<T, P> & operator/= (U const & s);
 
-		GLM_FUNC_DECL tmat3x4<T> & operator++ ();
-		GLM_FUNC_DECL tmat3x4<T> & operator-- ();
+		GLM_FUNC_DECL tmat3x4<T, P> & operator++ ();
+		GLM_FUNC_DECL tmat3x4<T, P> & operator-- ();
 	};
 
 	// Binary operators
-	template <typename T>
-	tmat3x4<T> operator+ (
-		tmat3x4<T> const & m,
-		typename tmat3x4<T>::value_type const & s);
-
-	template <typename T>
-	tmat3x4<T> operator+ (
-		tmat3x4<T> const & m1,
-		tmat3x4<T> const & m2);
-
-	template <typename T>
-	tmat3x4<T> operator- (
-		tmat3x4<T> const & m,
-		typename tmat3x4<T>::value_type const & s);
-
-	template <typename T>
-	tmat3x4<T> operator- (
-		tmat3x4<T> const & m1,
-		tmat3x4<T> const & m2);
-
-	template <typename T> 
-	tmat3x4<T> operator* (
-		tmat3x4<T> const & m, 
-		typename tmat3x4<T>::value_type const & s);
-
-	template <typename T>
-	tmat3x4<T> operator* (
-		typename tmat3x4<T>::value_type const & s,
-		tmat3x4<T> const & m);
-
-	template <typename T>
-	typename tmat3x4<T>::col_type operator* (
-		tmat3x4<T> const & m,
-		typename tmat3x4<T>::row_type const & v);
-
-	template <typename T> 
-	typename tmat3x4<T>::row_type operator* (
-		typename tmat3x4<T>::col_type const & v,
-		tmat3x4<T> const & m);
-
-	template <typename T>
-	tmat4x4<T> operator* (
-		tmat3x4<T> const & m1,
-		tmat4x3<T> const & m2);
+	template <typename T, precision P>
+	tmat3x4<T, P> operator+ (
+		tmat3x4<T, P> const & m,
+		typename tmat3x4<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat3x4<T, P> operator+ (
+		tmat3x4<T, P> const & m1,
+		tmat3x4<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x4<T, P> operator- (
+		tmat3x4<T, P> const & m,
+		typename tmat3x4<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat3x4<T, P> operator- (
+		tmat3x4<T, P> const & m1,
+		tmat3x4<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x4<T, P> operator* (
+		tmat3x4<T, P> const & m, 
+		typename tmat3x4<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat3x4<T, P> operator* (
+		typename tmat3x4<T, P>::value_type const & s,
+		tmat3x4<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat3x4<T, P>::col_type operator* (
+		tmat3x4<T, P> const & m,
+		typename tmat3x4<T, P>::row_type const & v);
+
+	template <typename T, precision P> 
+	typename tmat3x4<T, P>::row_type operator* (
+		typename tmat3x4<T, P>::col_type const & v,
+		tmat3x4<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator* (
+		tmat3x4<T, P> const & m1,
+		tmat4x3<T, P> const & m2);
 		
-	template <typename T>
-	tmat2x4<T> operator* (
-		tmat3x4<T> const & m1,
-		tmat2x3<T> const & m2);
+	template <typename T, precision P>
+	tmat2x4<T, P> operator* (
+		tmat3x4<T, P> const & m1,
+		tmat2x3<T, P> const & m2);
 		
-	template <typename T>
-	tmat3x4<T> operator* (
-		tmat3x4<T> const & m1,
-		tmat3x3<T> const & m2);
+	template <typename T, precision P>
+	tmat3x4<T, P> operator* (
+		tmat3x4<T, P> const & m1,
+		tmat3x3<T, P> const & m2);
 
-	template <typename T>
-	tmat3x4<T> operator/ (
-		tmat3x4<T> const & m,
-		typename tmat3x4<T>::value_type const & s);
+	template <typename T, precision P>
+	tmat3x4<T, P> operator/ (
+		tmat3x4<T, P> const & m,
+		typename tmat3x4<T, P>::value_type const & s);
 
-	template <typename T>
-	tmat3x4<T> operator/ (
-		typename tmat3x4<T>::value_type const & s,
-		tmat3x4<T> const & m);
+	template <typename T, precision P>
+	tmat3x4<T, P> operator/ (
+		typename tmat3x4<T, P>::value_type const & s,
+		tmat3x4<T, P> const & m);
 
 	// Unary constant operators
-	template <typename T>
-	tmat3x4<T> const operator- (
-		tmat3x4<T> const & m);
+	template <typename T, precision P>
+	tmat3x4<T, P> const operator- (
+		tmat3x4<T, P> const & m);
 
-	template <typename T> 
-	tmat3x4<T> const operator-- (
-		tmat3x4<T> const & m,
+	template <typename T, precision P>
+	tmat3x4<T, P> const operator-- (
+		tmat3x4<T, P> const & m,
 		int);
 
-	template <typename T> 
-	tmat3x4<T> const operator++ (
-		tmat3x4<T> const & m,
+	template <typename T, precision P>
+	tmat3x4<T, P> const operator++ (
+		tmat3x4<T, P> const & m,
 		int);
 
 }//namespace detail

+ 201 - 201
glm/core/type_mat3x4.inl

@@ -29,20 +29,20 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat3x4<T>::size_type tmat3x4<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat3x4<T, P>::size_type tmat3x4<T, P>::length() const
 	{
 		return 3;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x4<T>::size_type tmat3x4<T>::col_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::size_type tmat3x4<T, P>::col_size()
 	{
 		return 4;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x4<T>::size_type tmat3x4<T>::row_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::size_type tmat3x4<T, P>::row_size()
 	{
 		return 3;
 	}
@@ -50,9 +50,9 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x4<T>::col_type & 
-	tmat3x4<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::col_type &
+	tmat3x4<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -61,9 +61,9 @@ namespace detail
 		return this->value[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x4<T>::col_type const & 
-	tmat3x4<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::col_type const &
+	tmat3x4<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -75,18 +75,18 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Constructors
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4()
 	{
 		this->value[0] = col_type(1, 0, 0, 0);
 		this->value[1] = col_type(0, 1, 0, 0);
 		this->value[2] = col_type(0, 0, 1, 0);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = m.value[0];
@@ -94,15 +94,15 @@ namespace detail
 		this->value[2] = m.value[2];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
 		ctor
 	)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
 		value_type const & s
 	)
@@ -113,8 +113,8 @@ namespace detail
 		this->value[2] = col_type(Zero, Zero, s, Zero);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
 		value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0,
 		value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1,
@@ -126,11 +126,11 @@ namespace detail
 		this->value[2] = col_type(x2, y2, z2, w2);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		col_type const & v0, 
-		col_type const & v1, 
+		col_type const & v0,
+		col_type const & v1,
 		col_type const & v2
 	)
 	{
@@ -141,29 +141,29 @@ namespace detail
 
 	//////////////////////////////////////
 	// Convertion constructors
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_DECL tmat3x4<T>::tmat3x4
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_DECL tmat3x4<T, P>::tmat3x4
 	(
 		U const & s
 	)
 	{
 		value_type const Zero(0);
-		this->value[0] = tvec4<T>(value_type(s), Zero, Zero, Zero);
-		this->value[1] = tvec4<T>(Zero, value_type(s), Zero, Zero);
-		this->value[2] = tvec4<T>(Zero, Zero, value_type(s), Zero);
+		this->value[0] = tvec4<T, P>(value_type(s), Zero, Zero, Zero);
+		this->value[1] = tvec4<T, P>(Zero, value_type(s), Zero, Zero);
+		this->value[2] = tvec4<T, P>(Zero, Zero, value_type(s), Zero);
 	}
 	
-	template <typename T> 
+	template <typename T, precision P>
 	template <
-		typename X1, typename Y1, typename Z1, typename W1, 
-		typename X2, typename Y2, typename Z2, typename W2, 
-		typename X3, typename Y3, typename Z3, typename W3>  
-	GLM_FUNC_DECL tmat3x4<T>::tmat3x4
+		typename X1, typename Y1, typename Z1, typename W1,
+		typename X2, typename Y2, typename Z2, typename W2,
+		typename X3, typename Y3, typename Z3, typename W3>
+	GLM_FUNC_DECL tmat3x4<T, P>::tmat3x4
 	(
-		X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1, 
-		X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2, 
-		X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3  
+		X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
+		X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2,
+		X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3
 	)
 	{
 		this->value[0] = col_type(value_type(x1), value_type(y1), value_type(z1), value_type(w1));
@@ -171,13 +171,13 @@ namespace detail
 		this->value[2] = col_type(value_type(x3), value_type(y3), value_type(z3), value_type(w3));
 	}
 	
-	template <typename T> 
-	template <typename V1, typename V2, typename V3> 
-	GLM_FUNC_DECL tmat3x4<T>::tmat3x4
+	template <typename T, precision P>
+	template <typename V1, typename V2, typename V3>
+	GLM_FUNC_DECL tmat3x4<T, P>::tmat3x4
 	(
-		tvec4<V1> const & v1, 
-		tvec4<V2> const & v2, 
-		tvec4<V3> const & v3
+		tvec4<V1, P> const & v1,
+		tvec4<V2, P> const & v2,
+		tvec4<V3, P> const & v3
 	)
 	{
 		this->value[0] = col_type(v1);
@@ -186,11 +186,11 @@ namespace detail
 	}
 
 	// Conversion
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat3x4<U> const & m
+		tmat3x4<U, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -198,21 +198,21 @@ namespace detail
 		this->value[2] = col_type(m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
-		this->value[0] = col_type(m[0], detail::tvec2<T>(0));
-		this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
+		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
 		this->value[2] = col_type(T(0), T(0), T(1), T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
@@ -220,10 +220,10 @@ namespace detail
 		this->value[2] = col_type(m[2], T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -231,10 +231,10 @@ namespace detail
 		this->value[2] = col_type(m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
@@ -242,21 +242,21 @@ namespace detail
 		this->value[2] = col_type(T(0), T(0), T(1), T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
-		this->value[0] = col_type(m[0], detail::tvec2<T>(0));
-		this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
+		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
 		this->value[2] = col_type(m[2], T(0), T(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -264,21 +264,21 @@ namespace detail
 		this->value[2] = col_type(T(0), T(0), T(1), T(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
-		this->value[0] = col_type(m[0], detail::tvec2<T>(T(0)));
-		this->value[1] = col_type(m[1], detail::tvec2<T>(T(0)));
-		this->value[2] = col_type(m[2], detail::tvec2<T>(T(1), T(0)));
+		this->value[0] = col_type(m[0], detail::tvec2<T, P>(T(0)));
+		this->value[1] = col_type(m[1], detail::tvec2<T, P>(T(0)));
+		this->value[2] = col_type(m[2], detail::tvec2<T, P>(T(1), T(0)));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>::tmat3x4
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>::tmat3x4
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
@@ -289,10 +289,10 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Unary updatable operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator= 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator=
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -301,11 +301,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator= 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator=
 	(
-		tmat3x4<U> const & m
+		tmat3x4<U, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -314,9 +314,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator+= 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator+=
 	(
 		U const & s
 	)
@@ -327,11 +327,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator+= 
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator+=
 	(
-		tmat3x4<U> const & m
+		tmat3x4<U, P> const & m
 	)
 	{
 		this->value[0] += m[0];
@@ -340,9 +340,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator-=
 	(
 		U const & s
 	)
@@ -353,11 +353,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator-=
 	(
-		tmat3x4<U> const & m
+		tmat3x4<U, P> const & m
 	)
 	{
 		this->value[0] -= m[0];
@@ -366,9 +366,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator*=
 	(
 		U const & s
 	)
@@ -379,19 +379,19 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator*=
 	(
-		tmat3x4<U> const & m
+		tmat3x4<U, P> const & m
 	)
 	{
-		return (*this = tmat3x4<T>(*this * m));
+		return (*this = tmat3x4<T, P>(*this * m));
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> & tmat3x4<T>::operator/= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> & tmat3x4<T, P>::operator/=
 	(
 		U const & s
 	)
@@ -402,8 +402,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator++ ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator++ ()
 	{
 		++this->value[0];
 		++this->value[1];
@@ -411,8 +411,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T>& tmat3x4<T>::operator-- ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P>& tmat3x4<T, P>::operator-- ()
 	{
 		--this->value[0];
 		--this->value[1];
@@ -423,116 +423,116 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Binary operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator+
 	(
-		tmat3x4<T> const & m, 
-		typename tmat3x4<T>::value_type const & s
+		tmat3x4<T, P> const & m, 
+		typename tmat3x4<T, P>::value_type const & s
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m[0] + s,
 			m[1] + s,
 			m[2] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator+
 	(
-		tmat3x4<T> const & m1, 
-		tmat3x4<T> const & m2
+		tmat3x4<T, P> const & m1,
+		tmat3x4<T, P> const & m2
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m1[0] + m2[0],
 			m1[1] + m2[1],
 			m1[2] + m2[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator-
 	(
-		tmat3x4<T> const & m, 
-		typename tmat3x4<T>::value_type const & s
+		tmat3x4<T, P> const & m,
+		typename tmat3x4<T, P>::value_type const & s
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m[0] - s,
 			m[1] - s,
 			m[2] - s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator-
 	(
-		tmat3x4<T> const & m1, 
-		tmat3x4<T> const & m2
+		tmat3x4<T, P> const & m1,
+		tmat3x4<T, P> const & m2
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m1[0] - m2[0],
 			m1[1] - m2[1],
 			m1[2] - m2[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator*
 	(
-		tmat3x4<T> const & m, 
-		typename tmat3x4<T>::value_type const & s
+		tmat3x4<T, P> const & m,
+		typename tmat3x4<T, P>::value_type const & s
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator*
 	(
-		typename tmat3x4<T>::value_type const & s, 
-		tmat3x4<T> const & m
+		typename tmat3x4<T, P>::value_type const & s,
+		tmat3x4<T, P> const & m
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat3x4<T>::col_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::col_type operator*
 	(
-		tmat3x4<T> const & m, 
-		typename tmat3x4<T>::row_type const & v
+		tmat3x4<T, P> const & m,
+		typename tmat3x4<T, P>::row_type const & v
 	)
 	{
-		return typename tmat3x4<T>::col_type(
+		return typename tmat3x4<T, P>::col_type(
 			m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z,
 			m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z,
 			m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z,
 			m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat3x4<T>::row_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat3x4<T, P>::row_type operator*
 	(
-		typename tmat3x4<T>::col_type const & v, 
-		tmat3x4<T> const & m
+		typename tmat3x4<T, P>::col_type const & v,
+		tmat3x4<T, P> const & m
 	)
 	{
-		return typename tmat3x4<T>::row_type(
+		return typename tmat3x4<T, P>::row_type(
 			v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2] + v.w * m[0][3],
 			v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2] + v.w * m[1][3],
 			v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2] + v.w * m[2][3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator*
 	(
-		tmat3x4<T> const & m1, 
-		tmat4x3<T> const & m2
+		tmat3x4<T, P> const & m1,
+		tmat4x3<T, P> const & m2
 	)
 	{
 		const T SrcA00 = m1[0][0];
@@ -561,7 +561,7 @@ namespace detail
 		const T SrcB31 = m2[3][1];
 		const T SrcB32 = m2[3][2];
 
-		tmat4x4<T> Result(tmat4x4<T>::null);
+		tmat4x4<T, P> Result(tmat4x4<T, P>::null);
 		Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02;
 		Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02;
 		Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02;
@@ -581,14 +581,14 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator*
 	(
-		tmat3x4<T> const & m1, 
-		tmat2x3<T> const & m2
+		tmat3x4<T, P> const & m1,
+		tmat2x3<T, P> const & m2
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
@@ -599,14 +599,14 @@ namespace detail
 			m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator*
 	(
-		tmat3x4<T> const & m1, 
-		tmat3x3<T> const & m2
+		tmat3x4<T, P> const & m1,
+		tmat3x3<T, P> const & m2
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2],
@@ -621,66 +621,66 @@ namespace detail
 			m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator/
 	(
-		tmat3x4<T> const & m, 
-		typename tmat3x4<T>::value_type const & s
+		tmat3x4<T, P> const & m,
+		typename tmat3x4<T, P>::value_type const & s
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m[0] / s,
 			m[1] / s,
 			m[2] / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator/
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator/
 	(
-		typename tmat3x4<T>::value_type const & s, 
-		tmat3x4<T> const & m
+		typename tmat3x4<T, P>::value_type const & s,
+		tmat3x4<T, P> const & m
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			s / m[0],
 			s / m[1],
 			s / m[2]);
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> const operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> const operator-
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
-		return tmat3x4<T>(
-			-m[0], 
+		return tmat3x4<T, P>(
+			-m[0],
 			-m[1],
 			-m[2]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> const operator++ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> const operator++
 	(
-		tmat3x4<T> const & m, 
+		tmat3x4<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m[0] + T(1),
 			m[1] + T(1),
 			m[2] + T(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x4<T> const operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> const operator--
 	(
-		tmat3x4<T> const & m, 
+		tmat3x4<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m[0] - T(1),
 			m[1] - T(1),
 			m[2] - T(1));
@@ -689,21 +689,21 @@ namespace detail
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tmat3x4<T> const & m1, 
-		tmat3x4<T> const & m2
+		tmat3x4<T, P> const & m1,
+		tmat3x4<T, P> const & m2
 	)
 	{
 		return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tmat3x4<T> const & m1, 
-		tmat3x4<T> const & m2
+		tmat3x4<T, P> const & m1,
+		tmat3x4<T, P> const & m2
 	)
 	{
 		return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]);

+ 98 - 98
glm/core/type_mat4x2.hpp

@@ -35,16 +35,16 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
+	template <typename T, precision P>
 	struct tmat4x2
 	{
 		enum ctor{null};
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec2<T> col_type;
-		typedef tvec4<T> row_type;
-		typedef tmat4x2<T> type;
-		typedef tmat2x4<T> transpose_type;
+		typedef tvec2<T, P> col_type;
+		typedef tvec4<T, P> row_type;
+		typedef tmat4x2<T, P> type;
+		typedef tmat2x4<T, P> transpose_type;
 
 		static GLM_FUNC_DECL size_type col_size();
 		static GLM_FUNC_DECL size_type row_size();
@@ -96,130 +96,130 @@ namespace detail
 			
 		template <typename V1, typename V2, typename V3, typename V4>
 		GLM_FUNC_DECL explicit tmat4x2(
-			tvec2<V1> const & v1,
-			tvec2<V2> const & v2,
-			tvec2<V3> const & v3,
-			tvec2<V4> const & v4);
+			tvec2<V1, P> const & v1,
+			tvec2<V2, P> const & v2,
+			tvec2<V3, P> const & v3,
+			tvec2<V4, P> const & v4);
 
 		// Matrix conversions
 		template <typename U> 
-		GLM_FUNC_DECL explicit tmat4x2(tmat4x2<U> const & m);
+		GLM_FUNC_DECL explicit tmat4x2(tmat4x2<U, P> const & m);
 			
-		GLM_FUNC_DECL explicit tmat4x2(tmat2x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x2(tmat3x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x2(tmat4x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x2(tmat2x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x2(tmat3x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x2(tmat2x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x2(tmat4x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x2(tmat3x4<T> const & x);
+		GLM_FUNC_DECL explicit tmat4x2(tmat2x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x2(tmat3x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x2(tmat4x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x2(tmat2x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x2(tmat3x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x2(tmat2x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x2(tmat4x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x2(tmat3x4<T, P> const & x);
 
 		// Accesses
 		GLM_FUNC_DECL col_type & operator[](size_type i);
 		GLM_FUNC_DECL col_type const & operator[](size_type i) const;
 
 		// Unary updatable operators
-		GLM_FUNC_DECL tmat4x2<T>& operator=  (tmat4x2<T> const & m);
+		GLM_FUNC_DECL tmat4x2<T, P>& operator=  (tmat4x2<T, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat4x2<T>& operator=  (tmat4x2<U> const & m);
+		GLM_FUNC_DECL tmat4x2<T, P>& operator=  (tmat4x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat4x2<T>& operator+= (U const & s);
+		GLM_FUNC_DECL tmat4x2<T, P>& operator+= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat4x2<T>& operator+= (tmat4x2<U> const & m);
+		GLM_FUNC_DECL tmat4x2<T, P>& operator+= (tmat4x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat4x2<T>& operator-= (U const & s);
+		GLM_FUNC_DECL tmat4x2<T, P>& operator-= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat4x2<T>& operator-= (tmat4x2<U> const & m);
+		GLM_FUNC_DECL tmat4x2<T, P>& operator-= (tmat4x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat4x2<T>& operator*= (U const & s);
+		GLM_FUNC_DECL tmat4x2<T, P>& operator*= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tmat4x2<T>& operator*= (tmat4x2<U> const & m);
+		GLM_FUNC_DECL tmat4x2<T, P>& operator*= (tmat4x2<U, P> const & m);
 		template <typename U> 
-		GLM_FUNC_DECL tmat4x2<T>& operator/= (U const & s);
+		GLM_FUNC_DECL tmat4x2<T, P>& operator/= (U const & s);
 
-		GLM_FUNC_DECL tmat4x2<T>& operator++ ();
-		GLM_FUNC_DECL tmat4x2<T>& operator-- ();
+		GLM_FUNC_DECL tmat4x2<T, P>& operator++ ();
+		GLM_FUNC_DECL tmat4x2<T, P>& operator-- ();
 	};
 
 	// Binary operators
-	template <typename T> 
-	tmat4x2<T> operator+ (
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat4x2<T> operator+ (
-		tmat4x2<T> const & m1, 
-		tmat4x2<T> const & m2);
-
-	template <typename T> 
-	tmat4x2<T> operator- (
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat4x2<T> operator- (
-		tmat4x2<T> const & m1, 
-		tmat4x2<T> const & m2);
-
-	template <typename T> 
-	tmat4x2<T> operator* (
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::value_type const & s);
-
-	template <typename T> 
-	tmat4x2<T> operator* (
-		typename tmat4x2<T>::value_type const & s, 
-		tmat4x2<T> const & m);
-
-	template <typename T>
-	typename tmat4x2<T>::col_type operator* (
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::row_type const & v);
-
-	template <typename T> 
-	typename tmat4x2<T>::row_type operator* (
-		typename tmat4x2<T>::col_type const & v, 
-		tmat4x2<T> const & m);
-
-	template <typename T>
-	tmat3x2<T> operator* (
-		tmat4x2<T> const & m1, 
-		tmat3x4<T> const & m2);
+	template <typename T, precision P>
+	tmat4x2<T, P> operator+ (
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat4x2<T, P> operator+ (
+		tmat4x2<T, P> const & m1,
+		tmat4x2<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat4x2<T, P> operator- (
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat4x2<T, P> operator- (
+		tmat4x2<T, P> const & m1,
+		tmat4x2<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat4x2<T, P> operator* (
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat4x2<T, P> operator* (
+		typename tmat4x2<T, P>::value_type const & s,
+		tmat4x2<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat4x2<T, P>::col_type operator* (
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat4x2<T, P>::row_type operator* (
+		typename tmat4x2<T, P>::col_type const & v,
+		tmat4x2<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat3x2<T, P> operator* (
+		tmat4x2<T, P> const & m1,
+		tmat3x4<T, P> const & m2);
 		
-	template <typename T>
-	tmat4x2<T> operator* (
-		tmat4x2<T> const & m1, 
-		tmat4x4<T> const & m2);
+	template <typename T, precision P>
+	tmat4x2<T, P> operator* (
+		tmat4x2<T, P> const & m1,
+		tmat4x4<T, P> const & m2);
 		
-	template <typename T>
-	tmat2x3<T> operator* (
-		tmat4x3<T> const & m1, 
-		tmat2x4<T> const & m2);
+	template <typename T, precision P>
+	tmat2x3<T, P> operator* (
+		tmat4x3<T, P> const & m1,
+		tmat2x4<T, P> const & m2);
 
-	template <typename T> 
-	tmat4x2<T> operator/ (
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::value_type const & s);
+	template <typename T, precision P>
+	tmat4x2<T, P> operator/ (
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::value_type const & s);
 
-	template <typename T> 
-	tmat4x2<T> operator/ (
-		typename tmat4x2<T>::value_type const & s, 
-		tmat4x2<T> const & m);
+	template <typename T, precision P>
+	tmat4x2<T, P> operator/ (
+		typename tmat4x2<T, P>::value_type const & s,
+		tmat4x2<T, P> const & m);
 
 	// Unary constant operators
-	template <typename T> 
-	tmat4x2<T> const operator-  (
-		tmat4x2<T> const & m);
+	template <typename T, precision P>
+	tmat4x2<T, P> const operator-  (
+		tmat4x2<T, P> const & m);
 
-	template <typename T> 
-	tmat4x2<T> const operator-- (
-		tmat4x2<T> const & m, 
+	template <typename T, precision P>
+	tmat4x2<T, P> const operator-- (
+		tmat4x2<T, P> const & m,
 		int);
 
-	template <typename T> 
-	tmat4x2<T> const operator++ (
-		tmat4x2<T> const & m, 
+	template <typename T, precision P>
+	tmat4x2<T, P> const operator++ (
+		tmat4x2<T, P> const & m,
 		int);
 }//namespace detail
 }//namespace glm

+ 210 - 208
glm/core/type_mat4x2.inl

@@ -29,20 +29,20 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat4x2<T>::size_type tmat4x2<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat4x2<T, P>::size_type tmat4x2<T, P>::length() const
 	{
 		return 4;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x2<T>::size_type tmat4x2<T>::col_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x2<T, P>::size_type tmat4x2<T, P>::col_size()
 	{
 		return 2;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x2<T>::size_type tmat4x2<T>::row_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x2<T, P>::size_type tmat4x2<T, P>::row_size()
 	{
 		return 4;
 	}
@@ -50,9 +50,9 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x2<T>::col_type & 
-	tmat4x2<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x2<T, P>::col_type &
+	tmat4x2<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -61,9 +61,9 @@ namespace detail
 		return this->value[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x2<T>::col_type const & 
-	tmat4x2<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x2<T, P>::col_type const &
+	tmat4x2<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -75,8 +75,8 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Constructors
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2()
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2()
 	{
 		value_type const Zero(0);
 		value_type const One(1);
@@ -86,10 +86,10 @@ namespace detail
 		this->value[3] = col_type(Zero, Zero);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
 		this->value[0] = m.value[0];
@@ -98,15 +98,15 @@ namespace detail
 		this->value[3] = m.value[3];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
 		ctor
 	)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
 		value_type const & s
 	)
@@ -118,8 +118,8 @@ namespace detail
 		this->value[3] = col_type(Zero, Zero);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
 		value_type const & x0, value_type const & y0,
 		value_type const & x1, value_type const & y1,
@@ -133,11 +133,11 @@ namespace detail
 		this->value[3] = col_type(x3, y3);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		col_type const & v0, 
-		col_type const & v1, 
+		col_type const & v0,
+		col_type const & v1,
 		col_type const & v2,
 		col_type const & v3
 	)
@@ -150,29 +150,29 @@ namespace detail
 
 	//////////////////////////////////////
 	// Convertion constructors
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_DECL tmat4x2<T>::tmat4x2
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_DECL tmat4x2<T, P>::tmat4x2
 	(
 		U const & s
 	)
 	{
 		value_type const Zero(0);
-		this->value[0] = tvec2<T>(value_type(s), Zero);
-		this->value[1] = tvec2<T>(Zero, value_type(s));
-		this->value[2] = tvec2<T>(Zero, Zero);
-		this->value[3] = tvec2<T>(Zero, Zero);
+		this->value[0] = tvec2<T, P>(value_type(s), Zero);
+		this->value[1] = tvec2<T, P>(Zero, value_type(s));
+		this->value[2] = tvec2<T, P>(Zero, Zero);
+		this->value[3] = tvec2<T, P>(Zero, Zero);
 	}
 	
-	template <typename T> 
+	template <typename T, precision P>
 	template <
-		typename X1, typename Y1, 
-		typename X2, typename Y2, 
-		typename X3, typename Y3, 
-		typename X4, typename Y4>  
-	GLM_FUNC_DECL tmat4x2<T>::tmat4x2
+		typename X1, typename Y1,
+		typename X2, typename Y2,
+		typename X3, typename Y3,
+		typename X4, typename Y4>
+	GLM_FUNC_DECL tmat4x2<T, P>::tmat4x2
 	(
-		X1 const & x1, Y1 const & y1, 
+		X1 const & x1, Y1 const & y1,
 		X2 const & x2, Y2 const & y2,
 		X3 const & x3, Y3 const & y3,
 		X4 const & x4, Y4 const & y4
@@ -184,14 +184,14 @@ namespace detail
 		this->value[3] = col_type(value_type(x4), value_type(y4));
 	}
 	
-	template <typename T> 
-	template <typename V1, typename V2, typename V3, typename V4> 
-	GLM_FUNC_DECL tmat4x2<T>::tmat4x2
-	(
-		tvec2<V1> const & v1, 
-		tvec2<V2> const & v2, 
-		tvec2<V3> const & v3,
-		tvec2<V4> const & v4
+	template <typename T, precision P>
+	template <typename V1, typename V2, typename V3, typename V4>
+	GLM_FUNC_DECL tmat4x2<T, P>::tmat4x2
+	(
+		tvec2<V1, P> const & v1,
+		tvec2<V2, P> const & v2,
+		tvec2<V3, P> const & v3,
+		tvec2<V4, P> const & v4
 	)		
 	{
 		this->value[0] = col_type(v1);
@@ -201,11 +201,11 @@ namespace detail
 	}
 
 	// Conversion
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat4x2<U> const & m
+		tmat4x2<U, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -214,10 +214,10 @@ namespace detail
 		this->value[3] = col_type(m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -226,10 +226,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -238,10 +238,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -250,10 +250,10 @@ namespace detail
 		this->value[3] = col_type(m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -262,10 +262,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -274,10 +274,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -286,10 +286,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -298,10 +298,10 @@ namespace detail
 		this->value[3] = col_type(m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>::tmat4x2
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>::tmat4x2
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -313,10 +313,10 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Unary updatable operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>& tmat4x2<T>::operator= 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>& tmat4x2<T, P>::operator=
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -326,11 +326,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x2<T>& tmat4x2<T>::operator= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P>& tmat4x2<T, P>::operator=
 	(
-		tmat4x2<U> const & m
+		tmat4x2<U, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -340,9 +340,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> & tmat4x2<T, P>::operator+=
 	(
 		U const & s
 	)
@@ -354,11 +354,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> & tmat4x2<T, P>::operator+=
 	(
-		tmat4x2<U> const & m
+		tmat4x2<U, P> const & m
 	)
 	{
 		this->value[0] += m[0];
@@ -368,9 +368,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> & tmat4x2<T, P>::operator-=
 	(
 		U const & s
 	)
@@ -382,11 +382,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> & tmat4x2<T, P>::operator-=
 	(
-		tmat4x2<U> const & m
+		tmat4x2<U, P> const & m
 	)
 	{
 		this->value[0] -= m[0];
@@ -396,9 +396,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> & tmat4x2<T, P>::operator*=
 	(
 		U const & s
 	)
@@ -410,19 +410,19 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> & tmat4x2<T, P>::operator*=
 	(
-		tmat4x2<U> const & m
+		tmat4x2<U, P> const & m
 	)
 	{
-		return (*this = tmat4x2<T>(*this * m));
+		return (*this = tmat4x2<T, P>(*this * m));
 	}
 
-	template <typename T>
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator/= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> & tmat4x2<T, P>::operator/=
 	(
 		U const & s
 	)
@@ -434,8 +434,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator++ ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> & tmat4x2<T, P>::operator++ ()
 	{
 		++this->value[0];
 		++this->value[1];
@@ -444,8 +444,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> & tmat4x2<T>::operator-- ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> & tmat4x2<T, P>::operator-- ()
 	{
 		--this->value[0];
 		--this->value[1];
@@ -457,119 +457,121 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Binary operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator+
 	(
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::value_type const & s
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::value_type const & s
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m[0] + s,
 			m[1] + s,
 			m[2] + s,
 			m[3] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator+
 	(	
-		tmat4x2<T> const & m1, 
-		tmat4x2<T> const & m2
+		tmat4x2<T, P> const & m1,
+		tmat4x2<T, P> const & m2
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m1[0] + m2[0],
 			m1[1] + m2[1],
 			m1[2] + m2[2],
 			m1[3] + m2[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator-
 	(
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::value_type const & s
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::value_type const & s
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m[0] - s,
 			m[1] - s,
 			m[2] - s,
 			m[3] - s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator-
 	(	
-		tmat4x2<T> const & m1, 
-		tmat4x2<T> const & m2
+		tmat4x2<T, P> const & m1,
+		tmat4x2<T, P> const & m2
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m1[0] - m2[0],
 			m1[1] - m2[1],
 			m1[2] - m2[2],
 			m1[3] - m2[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator*
 	(
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::value_type const & s
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::value_type const & s
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s,
 			m[3] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator*
 	(
-		typename tmat4x2<T>::value_type const & s, 
-		tmat4x2<T> const & m
+		typename tmat4x2<T, P>::value_type const & s,
+		tmat4x2<T, P> const & m
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s,
 			m[3] * s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x2<T>::col_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x2<T, P>::col_type operator*
 	(
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::row_type const & v)
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::row_type const & v
+	)
 	{
-		return typename tmat4x2<T>::col_type(
+		return typename tmat4x2<T, P>::col_type(
 			m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
 			m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat4x2<T>::row_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x2<T, P>::row_type operator*
 	(
-		typename tmat4x2<T>::col_type const & v, 
-		tmat4x2<T> const & m) 
+		typename tmat4x2<T, P>::col_type const & v,
+		tmat4x2<T, P> const & m
+	)
 	{
-		return typename tmat4x2<T>::row_type(
+		return typename tmat4x2<T, P>::row_type(
 			v.x * m[0][0] + v.y * m[0][1],
 			v.x * m[1][0] + v.y * m[1][1],
 			v.x * m[2][0] + v.y * m[2][1],
 			v.x * m[3][0] + v.y * m[3][1]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat2x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x2<T, P> operator*
 	(
-		tmat4x2<T> const & m1, 
-		tmat2x4<T> const & m2
+		tmat4x2<T, P> const & m1,
+		tmat2x4<T, P> const & m2
 	)
 	{
 		T const SrcA00 = m1[0][0];
@@ -590,7 +592,7 @@ namespace detail
 		T const SrcB12 = m2[1][2];
 		T const SrcB13 = m2[1][3];
 
-		tmat2x2<T> Result(tmat2x2<T>::null);
+		tmat2x2<T, P> Result(tmat2x2<T, P>::null);
 		Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03;
 		Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03;
 		Result[1][0] = SrcA00 * SrcB10 + SrcA10 * SrcB11 + SrcA20 * SrcB12 + SrcA30 * SrcB13;
@@ -598,14 +600,14 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat3x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x2<T, P> operator*
 	(
-		tmat4x2<T> const & m1, 
-		tmat3x4<T> const & m2
+		tmat4x2<T, P> const & m1,
+		tmat3x4<T, P> const & m2
 	)
 	{
-		return tmat3x2<T>(
+		return tmat3x2<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
 			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3],
@@ -614,14 +616,14 @@ namespace detail
 			m1[0][1] * m2[2][0] + m1[1][1] * m2[2][1] + m1[2][1] * m2[2][2] + m1[3][1] * m2[2][3]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator*
 	(
-		tmat4x2<T> const & m1, 
-		tmat4x4<T> const & m2
+		tmat4x2<T, P> const & m1,
+		tmat4x4<T, P> const & m2
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
 			m1[0][0] * m2[1][0] + m1[1][0] * m2[1][1] + m1[2][0] * m2[1][2] + m1[3][0] * m2[1][3],
@@ -632,94 +634,94 @@ namespace detail
 			m1[0][1] * m2[3][0] + m1[1][1] * m2[3][1] + m1[2][1] * m2[3][2] + m1[3][1] * m2[3][3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator/
 	(
-		tmat4x2<T> const & m, 
-		typename tmat4x2<T>::value_type const & s
+		tmat4x2<T, P> const & m,
+		typename tmat4x2<T, P>::value_type const & s
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			m[0] / s,
 			m[1] / s,
 			m[2] / s,
-			m[3] / s);        
+			m[3] / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> operator/
 	(
-		typename tmat4x2<T>::value_type const & s, 
-		tmat4x2<T> const & m
+		typename tmat4x2<T, P>::value_type const & s,
+		tmat4x2<T, P> const & m
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			s / m[0],
 			s / m[1],
 			s / m[2],
-			s / m[3]);        
+			s / m[3]);
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> const operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> const operator-
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
-		return tmat4x2<T>(
+		return tmat4x2<T, P>(
 			-m[0], 
 			-m[1], 
 			-m[2], 
 			-m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> const operator++ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> const operator++
 	(
-		tmat4x2<T> const & m, 
+		tmat4x2<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat4x2<T>(
-			m[0] + typename tmat4x2<T>::value_type(1),
-			m[1] + typename tmat4x2<T>::value_type(1),
-			m[2] + typename tmat4x2<T>::value_type(1),
-			m[3] + typename tmat4x2<T>::value_type(1));
+		return tmat4x2<T, P>(
+			m[0] + typename tmat4x2<T, P>::value_type(1),
+			m[1] + typename tmat4x2<T, P>::value_type(1),
+			m[2] + typename tmat4x2<T, P>::value_type(1),
+			m[3] + typename tmat4x2<T, P>::value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x2<T> const operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x2<T, P> const operator--
 	(
-		tmat4x2<T> const & m, 
+		tmat4x2<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat4x2<T>(
-			m[0] - typename tmat4x2<T>::value_type(1),
-			m[1] - typename tmat4x2<T>::value_type(1),
-			m[2] - typename tmat4x2<T>::value_type(1),
-			m[3] - typename tmat4x2<T>::value_type(1));
+		return tmat4x2<T, P>(
+			m[0] - typename tmat4x2<T, P>::value_type(1),
+			m[1] - typename tmat4x2<T, P>::value_type(1),
+			m[2] - typename tmat4x2<T, P>::value_type(1),
+			m[3] - typename tmat4x2<T, P>::value_type(1));
 	}
 
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tmat4x2<T> const & m1, 
-		tmat4x2<T> const & m2
+		tmat4x2<T, P> const & m1,
+		tmat4x2<T, P> const & m2
 	)
 	{
 		return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tmat4x2<T> const & m1, 
-		tmat4x2<T> const & m2
+		tmat4x2<T, P> const & m1,
+		tmat4x2<T, P> const & m2
 	)
 	{
 		return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]);

+ 108 - 108
glm/core/type_mat4x3.hpp

@@ -35,16 +35,16 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> 
+	template <typename T, precision P>
 	struct tmat4x3
 	{
 		enum ctor{null};
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec3<T> col_type;
-		typedef tvec4<T> row_type;
-		typedef tmat4x3<T> type;
-		typedef tmat3x4<T> transpose_type;
+		typedef tvec3<T, P> col_type;
+		typedef tvec4<T, P> row_type;
+		typedef tmat4x3<T, P> type;
+		typedef tmat3x4<T, P> transpose_type;
 
 		static GLM_FUNC_DECL size_type col_size();
 		static GLM_FUNC_DECL size_type row_size();
@@ -70,7 +70,7 @@ namespace detail
 			value_type const & x2, value_type const & y2, value_type const & z2,
 			value_type const & x3, value_type const & y3, value_type const & z3);
 		GLM_FUNC_DECL explicit tmat4x3(
-			col_type const & v0, 
+			col_type const & v0,
 			col_type const & v1,
 			col_type const & v2,
 			col_type const & v3);
@@ -94,130 +94,130 @@ namespace detail
 			
 		template <typename V1, typename V2, typename V3, typename V4>
 		GLM_FUNC_DECL explicit tmat4x3(
-			tvec3<V1> const & v1,
-			tvec3<V2> const & v2,
-			tvec3<V3> const & v3,
-			tvec3<V4> const & v4);
+			tvec3<V1, P> const & v1,
+			tvec3<V2, P> const & v2,
+			tvec3<V3, P> const & v3,
+			tvec3<V4, P> const & v4);
 
 		// Matrix conversions
 		template <typename U>
-		GLM_FUNC_DECL explicit tmat4x3(tmat4x3<U> const & m);
+		GLM_FUNC_DECL explicit tmat4x3(tmat4x3<U, P> const & m);
 			
-		GLM_FUNC_DECL explicit tmat4x3(tmat2x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x3(tmat3x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x3(tmat4x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x3(tmat2x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x3(tmat3x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x3(tmat2x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x3(tmat4x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x3(tmat3x4<T> const & x);
+		GLM_FUNC_DECL explicit tmat4x3(tmat2x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x3(tmat3x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x3(tmat4x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x3(tmat2x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x3(tmat3x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x3(tmat2x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x3(tmat4x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x3(tmat3x4<T, P> const & x);
 
 		// Accesses
 		col_type & operator[](size_type i);
 		col_type const & operator[](size_type i) const;
 
 		// Unary updatable operators
-		GLM_FUNC_DECL tmat4x3<T> & operator=  (tmat4x3<T> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat4x3<T> & operator=  (tmat4x3<U> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat4x3<T> & operator+= (U const & s);
-		template <typename U> 
-		GLM_FUNC_DECL tmat4x3<T> & operator+= (tmat4x3<U> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat4x3<T> & operator-= (U const & s);
-		template <typename U> 
-		GLM_FUNC_DECL tmat4x3<T> & operator-= (tmat4x3<U> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat4x3<T> & operator*= (U const & s);
-		template <typename U> 
-		GLM_FUNC_DECL tmat4x3<T> & operator*= (tmat4x3<U> const & m);
-		template <typename U> 
-		GLM_FUNC_DECL tmat4x3<T> & operator/= (U const & s);
+		GLM_FUNC_DECL tmat4x3<T, P> & operator=  (tmat4x3<T, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat4x3<T, P> & operator=  (tmat4x3<U, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat4x3<T, P> & operator+= (U const & s);
+		template <typename U>
+		GLM_FUNC_DECL tmat4x3<T, P> & operator+= (tmat4x3<U, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat4x3<T, P> & operator-= (U const & s);
+		template <typename U>
+		GLM_FUNC_DECL tmat4x3<T, P> & operator-= (tmat4x3<U, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat4x3<T, P> & operator*= (U const & s);
+		template <typename U>
+		GLM_FUNC_DECL tmat4x3<T, P> & operator*= (tmat4x3<U, P> const & m);
+		template <typename U>
+		GLM_FUNC_DECL tmat4x3<T, P> & operator/= (U const & s);
 
-		GLM_FUNC_DECL tmat4x3<T> & operator++ ();
-		GLM_FUNC_DECL tmat4x3<T> & operator-- ();
+		GLM_FUNC_DECL tmat4x3<T, P> & operator++ ();
+		GLM_FUNC_DECL tmat4x3<T, P> & operator-- ();
 	};
 
 	// Binary operators
-	template <typename T>
-	tmat4x3<T> operator+ (
-		tmat4x3<T> const & m,
-		typename tmat4x3<T>::value_type const & s);
-
-	template <typename T>
-	tmat4x3<T> operator+ (
-		tmat4x3<T> const & m1,
-		tmat4x3<T> const & m2);
-
-	template <typename T>
-	tmat4x3<T> operator- (
-		tmat4x3<T> const & m,
-		typename tmat4x3<T>::value_type const & s);
-
-	template <typename T>
-	tmat4x3<T> operator- (
-		tmat4x3<T> const & m1,
-		tmat4x3<T> const & m2);
-
-	template <typename T>
-	tmat4x3<T> operator* (
-		tmat4x3<T> const & m,
-		typename tmat4x3<T>::value_type const & s);
-
-	template <typename T>
-	tmat4x3<T> operator* (
-		typename tmat4x3<T>::value_type const & s,
-		tmat4x3<T> const & m);
-
-	template <typename T>
-	typename tmat4x3<T>::col_type operator* (
-		tmat4x3<T> const & m, 
-		typename tmat4x3<T>::row_type const & v);
-
-	template <typename T>
-	typename tmat4x3<T>::row_type operator* (
-		typename tmat4x3<T>::col_type const & v,
-		tmat4x3<T> const & m);
-
-	template <typename T>
-	tmat2x3<T> operator* (
-		tmat4x3<T> const & m1,
-		tmat2x4<T> const & m2);
-
-	template <typename T>
-	tmat3x3<T> operator* (
-		tmat4x3<T> const & m1,
-		tmat3x4<T> const & m2);
+	template <typename T, precision P>
+	tmat4x3<T, P> operator+ (
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat4x3<T, P> operator+ (
+		tmat4x3<T, P> const & m1,
+		tmat4x3<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat4x3<T, P> operator- (
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat4x3<T, P> operator- (
+		tmat4x3<T, P> const & m1,
+		tmat4x3<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat4x3<T, P> operator* (
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat4x3<T, P> operator* (
+		typename tmat4x3<T, P>::value_type const & s,
+		tmat4x3<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat4x3<T, P>::col_type operator* (
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat4x3<T, P>::row_type operator* (
+		typename tmat4x3<T, P>::col_type const & v,
+		tmat4x3<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat2x3<T, P> operator* (
+		tmat4x3<T, P> const & m1,
+		tmat2x4<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x3<T, P> operator* (
+		tmat4x3<T, P> const & m1,
+		tmat3x4<T, P> const & m2);
 		
-	template <typename T>
-	tmat4x3<T> operator* (
-		tmat4x3<T> const & m1, 
-		tmat4x4<T> const & m2);
+	template <typename T, precision P>
+	tmat4x3<T, P> operator* (
+		tmat4x3<T, P> const & m1,
+		tmat4x4<T, P> const & m2);
 
-	template <typename T>
-	tmat4x3<T> operator/ (
-		tmat4x3<T> const & m,
-		typename tmat4x3<T>::value_type const & s);
+	template <typename T, precision P>
+	tmat4x3<T, P> operator/ (
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::value_type const & s);
 
-	template <typename T> 
-	tmat4x3<T> operator/ (
-		typename tmat4x3<T>::value_type const & s, 
-		tmat4x3<T> const & m);
+	template <typename T, precision P>
+	tmat4x3<T, P> operator/ (
+		typename tmat4x3<T, P>::value_type const & s,
+		tmat4x3<T, P> const & m);
 
 	// Unary constant operators
-	template <typename T>
-	tmat4x3<T> const operator- (
-		tmat4x3<T> const & m);
+	template <typename T, precision P>
+	tmat4x3<T, P> const operator- (
+		tmat4x3<T, P> const & m);
 
-	template <typename T>
-	tmat4x3<T> const operator-- (
-		tmat4x3<T> const & m,
+	template <typename T, precision P>
+	tmat4x3<T, P> const operator-- (
+		tmat4x3<T, P> const & m,
 		int);
 
-	template <typename T>
-	tmat4x3<T> const operator++ (
-		tmat4x3<T> const & m,
+	template <typename T, precision P>
+	tmat4x3<T, P> const operator++ (
+		tmat4x3<T, P> const & m,
 		int);
 }//namespace detail
 }//namespace glm

+ 200 - 200
glm/core/type_mat4x3.inl

@@ -29,20 +29,20 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat4x3<T>::size_type tmat4x3<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat4x3<T, P>::size_type tmat4x3<T, P>::length() const
 	{
 		return 4;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x3<T>::size_type tmat4x3<T>::col_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x3<T, P>::size_type tmat4x3<T, P>::col_size()
 	{
 		return 3;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x3<T>::size_type tmat4x3<T>::row_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x3<T, P>::size_type tmat4x3<T, P>::row_size()
 	{
 		return 4;
 	}
@@ -50,9 +50,9 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x3<T>::col_type & 
-	tmat4x3<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x3<T, P>::col_type & 
+	tmat4x3<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -61,9 +61,9 @@ namespace detail
 		return this->value[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x3<T>::col_type const & 
-	tmat4x3<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x3<T, P>::col_type const & 
+	tmat4x3<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -75,8 +75,8 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Constructors
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3()
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3()
 	{
 		value_type const Zero(0);
 		value_type const One(1);
@@ -86,10 +86,10 @@ namespace detail
 		this->value[3] = col_type(Zero, Zero, Zero);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = m.value[0];
@@ -98,15 +98,15 @@ namespace detail
 		this->value[3] = m.value[3];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
 		ctor
 	)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
 		value_type const & s
 	)
@@ -118,8 +118,8 @@ namespace detail
 		this->value[3] = col_type(Zero, Zero, Zero);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
 		value_type const & x0, value_type const & y0, value_type const & z0,
 		value_type const & x1, value_type const & y1, value_type const & z1,
@@ -133,8 +133,8 @@ namespace detail
 		this->value[3] = col_type(x3, y3, z3);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
 		col_type const & v0, 
 		col_type const & v1, 
@@ -150,31 +150,31 @@ namespace detail
 
 	//////////////////////////////////////
 	// Convertion constructors
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_DECL tmat4x3<T>::tmat4x3
+	GLM_FUNC_DECL tmat4x3<T, P>::tmat4x3
 	(
 		U const & s
 	)
 	{
 		value_type const Zero(0);
-		this->value[0] = tvec3<T>(value_type(s), Zero, Zero);
-		this->value[1] = tvec3<T>(Zero, value_type(s), Zero);
-		this->value[2] = tvec3<T>(Zero, Zero, value_type(s));
-		this->value[3] = tvec3<T>(Zero, Zero, Zero);
+		this->value[0] = tvec3<T, P>(value_type(s), Zero, Zero);
+		this->value[1] = tvec3<T, P>(Zero, value_type(s), Zero);
+		this->value[2] = tvec3<T, P>(Zero, Zero, value_type(s));
+		this->value[3] = tvec3<T, P>(Zero, Zero, Zero);
 	}
 	
-	template <typename T> 
+	template <typename T, precision P> 
 	template <
-		typename X1, typename Y1, typename Z1, 
-		typename X2, typename Y2, typename Z2, 
-		typename X3, typename Y3, typename Z3, 
-		typename X4, typename Y4, typename Z4>  
-	GLM_FUNC_DECL tmat4x3<T>::tmat4x3
-	(
-		X1 const & x1, Y1 const & y1, Z1 const & z1, 
-		X2 const & x2, Y2 const & y2, Z2 const & z2, 
-		X3 const & x3, Y3 const & y3, Z3 const & z3, 
+		typename X1, typename Y1, typename Z1,
+		typename X2, typename Y2, typename Z2,
+		typename X3, typename Y3, typename Z3,
+		typename X4, typename Y4, typename Z4>
+	GLM_FUNC_DECL tmat4x3<T, P>::tmat4x3
+	(
+		X1 const & x1, Y1 const & y1, Z1 const & z1,
+		X2 const & x2, Y2 const & y2, Z2 const & z2,
+		X3 const & x3, Y3 const & y3, Z3 const & z3,
 		X4 const & x4, Y4 const & y4, Z4 const & z4
 	)		
 	{
@@ -184,14 +184,14 @@ namespace detail
 		this->value[3] = col_type(value_type(x4), value_type(y4), value_type(z4));
 	}
 	
-	template <typename T> 
-	template <typename V1, typename V2, typename V3, typename V4> 
-	GLM_FUNC_DECL tmat4x3<T>::tmat4x3
+	template <typename T, precision P>
+	template <typename V1, typename V2, typename V3, typename V4>
+	GLM_FUNC_DECL tmat4x3<T, P>::tmat4x3
 	(
-		tvec3<V1> const & v1, 
-		tvec3<V2> const & v2, 
-		tvec3<V3> const & v3,
-		tvec3<V4> const & v4
+		tvec3<V1, P> const & v1,
+		tvec3<V2, P> const & v2,
+		tvec3<V3, P> const & v3,
+		tvec3<V4, P> const & v4
 	)
 	{
 		this->value[0] = col_type(v1);
@@ -203,11 +203,11 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Matrix conversions
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat4x3<U> const & m
+		tmat4x3<U, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -216,10 +216,10 @@ namespace detail
 		this->value[3] = col_type(m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], value_type(0));
@@ -228,10 +228,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -240,10 +240,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -252,10 +252,10 @@ namespace detail
 		this->value[3] = col_type(m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -264,10 +264,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], value_type(0));
@@ -276,10 +276,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -288,10 +288,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], value_type(0));
@@ -300,10 +300,10 @@ namespace detail
 		this->value[3] = col_type(m[3], value_type(0));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>::tmat4x3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>::tmat4x3
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -315,10 +315,10 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Unary updatable operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>& tmat4x3<T>::operator= 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>& tmat4x3<T, P>::operator=
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -328,11 +328,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x3<T>& tmat4x3<T>::operator= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P>& tmat4x3<T, P>::operator=
 	(
-		tmat4x3<U> const & m
+		tmat4x3<U, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -342,9 +342,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> & tmat4x3<T, P>::operator+=
 	(
 		U const & s
 	)
@@ -356,11 +356,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> & tmat4x3<T, P>::operator+=
 	(
-		tmat4x3<U> const & m
+		tmat4x3<U, P> const & m
 	)
 	{
 		this->value[0] += m[0];
@@ -370,9 +370,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> & tmat4x3<T, P>::operator-=
 	(
 		U const & s
 	)
@@ -384,11 +384,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> & tmat4x3<T, P>::operator-=
 	(
-		tmat4x3<U> const & m
+		tmat4x3<U, P> const & m
 	)
 	{
 		this->value[0] -= m[0];
@@ -398,9 +398,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> & tmat4x3<T, P>::operator*=
 	(
 		U const & s
 	)
@@ -412,19 +412,19 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator*= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> & tmat4x3<T, P>::operator*=
 	(
-		tmat4x3<U> const & m
+		tmat4x3<U, P> const & m
 	)
 	{
-		return (*this = tmat4x3<T>(*this * m));
+		return (*this = tmat4x3<T, P>(*this * m));
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator/= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> & tmat4x3<T, P>::operator/=
 	(
 		U const & s
 	)
@@ -436,8 +436,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator++ ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> & tmat4x3<T, P>::operator++ ()
 	{
 		++this->value[0];
 		++this->value[1];
@@ -446,8 +446,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> & tmat4x3<T>::operator-- ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> & tmat4x3<T, P>::operator-- ()
 	{
 		--this->value[0];
 		--this->value[1];
@@ -459,111 +459,111 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Binary operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator+ (
-		tmat4x3<T> const & m, 
-		typename tmat4x3<T>::value_type const & s)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator+ (
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::value_type const & s)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m[0] + s,
 			m[1] + s,
 			m[2] + s,
 			m[3] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator+ (
-		tmat4x3<T> const & m1, 
-		tmat4x3<T> const & m2)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator+ (
+		tmat4x3<T, P> const & m1, 
+		tmat4x3<T, P> const & m2)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m1[0] + m2[0],
 			m1[1] + m2[1],
 			m1[2] + m2[2],
 			m1[3] + m2[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator- (
-		tmat4x3<T> const & m, 
-		typename tmat4x3<T>::value_type const & s)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator- (
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::value_type const & s)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m[0] - s,
 			m[1] - s,
 			m[2] - s,
 			m[3] - s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator- (
-		tmat4x3<T> const & m1, 
-		tmat4x3<T> const & m2)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator- (
+		tmat4x3<T, P> const & m1,
+		tmat4x3<T, P> const & m2)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m1[0] - m2[0],
 			m1[1] - m2[1],
 			m1[2] - m2[2],
 			m1[3] - m2[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator* (
-		tmat4x3<T> const & m, 
-		typename tmat4x3<T>::value_type const & s)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator* (
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::value_type const & s)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s,
 			m[3] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator* (
-		typename tmat4x3<T>::value_type const & s, 
-		tmat4x3<T> const & m)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator* (
+		typename tmat4x3<T, P>::value_type const & s,
+		tmat4x3<T, P> const & m)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s,
 			m[3] * s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x3<T>::col_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x3<T, P>::col_type operator*
 	(
-		tmat4x3<T> const & m, 
-		typename tmat4x3<T>::row_type const & v)
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::row_type const & v)
 	{
-		return typename tmat4x3<T>::col_type(
+		return typename tmat4x3<T, P>::col_type(
 			m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
 			m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w,
 			m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat4x3<T>::row_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x3<T, P>::row_type operator*
 	(
-		typename tmat4x3<T>::col_type const & v, 
-		tmat4x3<T> const & m) 
+		typename tmat4x3<T, P>::col_type const & v,
+		tmat4x3<T, P> const & m)
 	{
-		return typename tmat4x3<T>::row_type(
+		return typename tmat4x3<T, P>::row_type(
 			v.x * m[0][0] + v.y * m[0][1] + v.z * m[0][2],
 			v.x * m[1][0] + v.y * m[1][1] + v.z * m[1][2],
 			v.x * m[2][0] + v.y * m[2][1] + v.z * m[2][2],
 			v.x * m[3][0] + v.y * m[3][1] + v.z * m[3][2]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x3<T, P> operator*
 	(
-		tmat4x3<T> const & m1, 
-		tmat2x4<T> const & m2
+		tmat4x3<T, P> const & m1,
+		tmat2x4<T, P> const & m2
 	)
 	{
-		return tmat2x3<T>(
+		return tmat2x3<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3],
@@ -572,11 +572,11 @@ namespace detail
 			m1[0][2] * m2[1][0] + m1[1][2] * m2[1][1] + m1[2][2] * m2[1][2] + m1[3][2] * m2[1][3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat3x3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x3<T, P> operator*
 	(
-		tmat4x3<T> const & m1, 
-		tmat3x4<T> const & m2
+		tmat4x3<T, P> const & m1,
+		tmat3x4<T, P> const & m2
 	)
 	{
 		T const SrcA00 = m1[0][0];
@@ -605,7 +605,7 @@ namespace detail
 		T const SrcB22 = m2[2][2];
 		T const SrcB23 = m2[2][3];
 
-		tmat3x3<T> Result(tmat3x3<T>::null);
+		tmat3x3<T, P> Result(tmat3x3<T, P>::null);
 		Result[0][0] = SrcA00 * SrcB00 + SrcA10 * SrcB01 + SrcA20 * SrcB02 + SrcA30 * SrcB03;
 		Result[0][1] = SrcA01 * SrcB00 + SrcA11 * SrcB01 + SrcA21 * SrcB02 + SrcA31 * SrcB03;
 		Result[0][2] = SrcA02 * SrcB00 + SrcA12 * SrcB01 + SrcA22 * SrcB02 + SrcA32 * SrcB03;
@@ -618,14 +618,14 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator*
 	(
-		tmat4x3<T> const & m1, 
-		tmat4x4<T> const & m2
+		tmat4x3<T, P> const & m1,
+		tmat4x4<T, P> const & m2
 	)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3],
@@ -640,70 +640,70 @@ namespace detail
 			m1[0][2] * m2[3][0] + m1[1][2] * m2[3][1] + m1[2][2] * m2[3][2] + m1[3][2] * m2[3][3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator/
 	(
-		tmat4x3<T> const & m, 
-		typename tmat4x3<T>::value_type const & s
+		tmat4x3<T, P> const & m,
+		typename tmat4x3<T, P>::value_type const & s
 	)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m[0] / s,
 			m[1] / s,
 			m[2] / s,
-			m[3] / s);        
+			m[3] / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> operator/
 	(
-		typename tmat4x3<T>::value_type const & s, 
-		tmat4x3<T> const & m
+		typename tmat4x3<T, P>::value_type const & s,
+		tmat4x3<T, P> const & m
 	)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			s / m[0],
 			s / m[1],
 			s / m[2],
-			s / m[3]);        
+			s / m[3]);
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> const operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> const operator-
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
-		return tmat4x3<T>(
-			-m[0], 
+		return tmat4x3<T, P>(
+			-m[0],
 			-m[1],
 			-m[2],
 			-m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> const operator++ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> const operator++
 	(
-		tmat4x3<T> const & m, 
+		tmat4x3<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m[0] + T(1),
 			m[1] + T(1),
 			m[2] + T(1),
 			m[3] + T(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x3<T> const operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x3<T, P> const operator--
 	(
-		tmat4x3<T> const & m, 
+		tmat4x3<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat4x3<T>(
+		return tmat4x3<T, P>(
 			m[0] - T(1),
 			m[1] - T(1),
 			m[2] - T(1),
@@ -713,21 +713,21 @@ namespace detail
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tmat4x3<T> const & m1, 
-		tmat4x3<T> const & m2
+		tmat4x3<T, P> const & m1,
+		tmat4x3<T, P> const & m2
 	)
 	{
 		return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tmat4x3<T> const & m1, 
-		tmat4x3<T> const & m2
+		tmat4x3<T, P> const & m1,
+		tmat4x3<T, P> const & m2
 	)
 	{
 		return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]);

+ 130 - 130
glm/core/type_mat4x4.hpp

@@ -35,16 +35,16 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> 
+	template <typename T, precision P>
 	struct tmat4x4
 	{
 		enum ctor{null};
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec4<T> col_type;
-		typedef tvec4<T> row_type;
-		typedef tmat4x4<T> type;
-		typedef tmat4x4<T> transpose_type;
+		typedef tvec4<T, P> col_type;
+		typedef tvec4<T, P> row_type;
+		typedef tmat4x4<T, P> type;
+		typedef tmat4x4<T, P> transpose_type;
 
 		static GLM_FUNC_DECL size_type col_size();
 		static GLM_FUNC_DECL size_type row_size();
@@ -54,7 +54,7 @@ namespace detail
 	public:
 		/// Implementation detail
 		/// @cond DETAIL
-		GLM_FUNC_DECL tmat4x4<T> _inverse() const;
+		GLM_FUNC_DECL tmat4x4<T, P> _inverse() const;
 		/// @endcond
 
 	private:
@@ -76,7 +76,7 @@ namespace detail
 			value_type const & x2, value_type const & y2, value_type const & z2, value_type const & w2,
 			value_type const & x3, value_type const & y3, value_type const & z3, value_type const & w3);
 		GLM_FUNC_DECL explicit tmat4x4(
-			col_type const & v0, 
+			col_type const & v0,
 			col_type const & v1,
 			col_type const & v2,
 			col_type const & v3);
@@ -98,157 +98,157 @@ namespace detail
 			X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3,
 			X4 const & x4, Y4 const & y4, Z4 const & z4, W4 const & w4);
 			
-		template <typename V1, typename V2, typename V3, typename V4> 
+		template <typename V1, typename V2, typename V3, typename V4>
 		GLM_FUNC_DECL explicit tmat4x4(
-			tvec4<V1> const & v1,
-			tvec4<V2> const & v2,
-			tvec4<V3> const & v3,
-			tvec4<V4> const & v4);
+			tvec4<V1, P> const & v1,
+			tvec4<V2, P> const & v2,
+			tvec4<V3, P> const & v3,
+			tvec4<V4, P> const & v4);
 	
 		// Matrix conversions
 		template <typename U> 
-		GLM_FUNC_DECL explicit tmat4x4(tmat4x4<U> const & m);
+		GLM_FUNC_DECL explicit tmat4x4(tmat4x4<U, P> const & m);
 
-		GLM_FUNC_DECL explicit tmat4x4(tmat2x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x4(tmat3x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x4(tmat2x3<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x4(tmat3x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x4(tmat2x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x4(tmat4x2<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x4(tmat3x4<T> const & x);
-		GLM_FUNC_DECL explicit tmat4x4(tmat4x3<T> const & x);
+		GLM_FUNC_DECL explicit tmat4x4(tmat2x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x4(tmat3x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x4(tmat2x3<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x4(tmat3x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x4(tmat2x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x4(tmat4x2<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x4(tmat3x4<T, P> const & x);
+		GLM_FUNC_DECL explicit tmat4x4(tmat4x3<T, P> const & x);
 
 		// Accesses
 		GLM_FUNC_DECL col_type & operator[](size_type i);
 		GLM_FUNC_DECL col_type const & operator[](size_type i) const;
 
 		// Unary updatable operators
-		GLM_FUNC_DECL tmat4x4<T> & operator=  (tmat4x4<T> const & m);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator=  (tmat4x4<T, P> const & m);
 		template <typename U>
-		GLM_FUNC_DECL tmat4x4<T> & operator=  (tmat4x4<U> const & m);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator=  (tmat4x4<U, P> const & m);
 		template <typename U>
-		GLM_FUNC_DECL tmat4x4<T> & operator+= (U const & s);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator+= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tmat4x4<T> & operator+= (tmat4x4<U> const & m);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator+= (tmat4x4<U, P> const & m);
 		template <typename U>
-		GLM_FUNC_DECL tmat4x4<T> & operator-= (U const & s);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator-= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tmat4x4<T> & operator-= (tmat4x4<U> const & m);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator-= (tmat4x4<U, P> const & m);
 		template <typename U>
-		GLM_FUNC_DECL tmat4x4<T> & operator*= (U const & s);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator*= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tmat4x4<T> & operator*= (tmat4x4<U> const & m);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator*= (tmat4x4<U, P> const & m);
 		template <typename U>
-		GLM_FUNC_DECL tmat4x4<T> & operator/= (U const & s);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator/= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tmat4x4<T> & operator/= (tmat4x4<U> const & m);
-		GLM_FUNC_DECL tmat4x4<T> & operator++ ();
-		GLM_FUNC_DECL tmat4x4<T> & operator-- ();
+		GLM_FUNC_DECL tmat4x4<T, P> & operator/= (tmat4x4<U, P> const & m);
+		GLM_FUNC_DECL tmat4x4<T, P> & operator++ ();
+		GLM_FUNC_DECL tmat4x4<T, P> & operator-- ();
 	};
 
 	// Binary operators
-	template <typename T>
-	tmat4x4<T> operator+ (
-		tmat4x4<T> const & m,
-		typename tmat4x4<T>::value_type const & s);
-
-	template <typename T>
-	tmat4x4<T> operator+ (
-		typename tmat4x4<T>::value_type const & s,
-		tmat4x4<T> const & m);
-
-	template <typename T> 
-	tmat4x4<T> operator+ (
-		tmat4x4<T> const & m1, 
-		tmat4x4<T> const & m2);
-
-	template <typename T> 
-	tmat4x4<T> operator- (
-		tmat4x4<T> const & m, 
-		typename tmat4x4<T>::value_type const & s);
-
-	template <typename T> 
-	tmat4x4<T> operator- (
-		typename tmat4x4<T>::value_type const & s,
-		tmat4x4<T> const & m);
-
-	template <typename T>
-	tmat4x4<T> operator- (
-		tmat4x4<T> const & m1,
-		tmat4x4<T> const & m2);
-
-	template <typename T>
-	tmat4x4<T> operator* (
-		tmat4x4<T> const & m,
-		typename tmat4x4<T>::value_type const & s);
-
-	template <typename T>
-	tmat4x4<T> operator* (
-		typename tmat4x4<T>::value_type const & s,
-		tmat4x4<T> const & m);
-
-	template <typename T>
-	typename tmat4x4<T>::col_type operator* (
-		tmat4x4<T> const & m,
-		typename tmat4x4<T>::row_type const & v);
-
-	template <typename T>
-	typename tmat4x4<T>::row_type operator* (
-		typename tmat4x4<T>::col_type const & v,
-		tmat4x4<T> const & m);
+	template <typename T, precision P>
+	tmat4x4<T, P> operator+ (
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator+ (
+		typename tmat4x4<T, P>::value_type const & s,
+		tmat4x4<T, P> const & m);
+
+	template <typename T, precision P> 
+	tmat4x4<T, P> operator+ (
+		tmat4x4<T, P> const & m1, 
+		tmat4x4<T, P> const & m2);
+
+	template <typename T, precision P> 
+	tmat4x4<T, P> operator- (
+		tmat4x4<T, P> const & m, 
+		typename tmat4x4<T, P>::value_type const & s);
+
+	template <typename T, precision P> 
+	tmat4x4<T, P> operator- (
+		typename tmat4x4<T, P>::value_type const & s,
+		tmat4x4<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator- (
+		tmat4x4<T, P> const & m1,
+		tmat4x4<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator* (
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator* (
+		typename tmat4x4<T, P>::value_type const & s,
+		tmat4x4<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat4x4<T, P>::col_type operator* (
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat4x4<T, P>::row_type operator* (
+		typename tmat4x4<T, P>::col_type const & v,
+		tmat4x4<T, P> const & m);
 		
-	template <typename T>
-	tmat2x4<T> operator* (
-		tmat4x4<T> const & m1,
-		tmat2x4<T> const & m2);
-
-	template <typename T>
-	tmat3x4<T> operator* (
-		tmat4x4<T> const & m1,
-		tmat3x4<T> const & m2);
-
-	template <typename T>
-	tmat4x4<T> operator* (
-		tmat4x4<T> const & m1,
-		tmat4x4<T> const & m2);
-
-	template <typename T>
-	tmat4x4<T> operator/ (
-		tmat4x4<T> const & m,
-		typename tmat4x4<T>::value_type const & s);
-
-	template <typename T>
-	tmat4x4<T> operator/ (
-		typename tmat4x4<T>::value_type const & s,
-		tmat4x4<T> const & m);
-
-	template <typename T>
-	typename tmat4x4<T>::col_type operator/ (
-		tmat4x4<T> const & m,
-		typename tmat4x4<T>::row_type const & v);
-
-	template <typename T>
-	typename tmat4x4<T>::row_type operator/ (
-		typename tmat4x4<T>::col_type & v,
-		tmat4x4<T> const & m);
-
-	template <typename T>
-	tmat4x4<T> operator/ (
-		tmat4x4<T> const & m1,
-		tmat4x4<T> const & m2);
+	template <typename T, precision P>
+	tmat2x4<T, P> operator* (
+		tmat4x4<T, P> const & m1,
+		tmat2x4<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat3x4<T, P> operator* (
+		tmat4x4<T, P> const & m1,
+		tmat3x4<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator* (
+		tmat4x4<T, P> const & m1,
+		tmat4x4<T, P> const & m2);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator/ (
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::value_type const & s);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator/ (
+		typename tmat4x4<T, P>::value_type const & s,
+		tmat4x4<T, P> const & m);
+
+	template <typename T, precision P>
+	typename tmat4x4<T, P>::col_type operator/ (
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::row_type const & v);
+
+	template <typename T, precision P>
+	typename tmat4x4<T, P>::row_type operator/ (
+		typename tmat4x4<T, P>::col_type & v,
+		tmat4x4<T, P> const & m);
+
+	template <typename T, precision P>
+	tmat4x4<T, P> operator/ (
+		tmat4x4<T, P> const & m1,
+		tmat4x4<T, P> const & m2);
 
 	// Unary constant operators
-	template <typename T>
-	tmat4x4<T> const operator-  (
-		tmat4x4<T> const & m);
+	template <typename T, precision P>
+	tmat4x4<T, P> const operator-  (
+		tmat4x4<T, P> const & m);
 
-	template <typename T>
-	tmat4x4<T> const operator-- (
-		tmat4x4<T> const & m, int);
+	template <typename T, precision P>
+	tmat4x4<T, P> const operator-- (
+		tmat4x4<T, P> const & m, int);
 
-	template <typename T>
-	tmat4x4<T> const operator++ (
-		tmat4x4<T> const & m, int);
+	template <typename T, precision P>
+	tmat4x4<T, P> const operator++ (
+		tmat4x4<T, P> const & m, int);
 
 }//namespace detail
 }//namespace glm

+ 254 - 254
glm/core/type_mat4x4.inl

@@ -29,20 +29,20 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat4x4<T>::size_type tmat4x4<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tmat4x4<T, P>::size_type tmat4x4<T, P>::length() const
 	{
 		return 4;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x4<T>::size_type tmat4x4<T>::col_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::size_type tmat4x4<T, P>::col_size()
 	{
 		return 4;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x4<T>::size_type tmat4x4<T>::row_size()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::size_type tmat4x4<T, P>::row_size()
 	{
 		return 4;
 	}
@@ -50,9 +50,9 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x4<T>::col_type & 
-	tmat4x4<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::col_type &
+	tmat4x4<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -61,9 +61,9 @@ namespace detail
 		return this->value[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tmat4x4<T>::col_type const & 
-	tmat4x4<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::col_type const &
+	tmat4x4<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -75,8 +75,8 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Constructors
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4()
 	{
 		value_type Zero(0);
 		value_type One(1);
@@ -85,11 +85,11 @@ namespace detail
 		this->value[2] = col_type(Zero, Zero, One, Zero);
 		this->value[3] = col_type(Zero, Zero, Zero, One);
 	}
-
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		this->value[0] = m.value[0];
@@ -98,15 +98,15 @@ namespace detail
 		this->value[3] = m.value[3];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
 		ctor
 	)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
 		value_type const & s
 	)
@@ -118,8 +118,8 @@ namespace detail
 		this->value[3] = col_type(Zero, Zero, Zero, s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
 		value_type const & x0, value_type const & y0, value_type const & z0, value_type const & w0,
 		value_type const & x1, value_type const & y1, value_type const & z1, value_type const & w1,
@@ -133,11 +133,11 @@ namespace detail
 		this->value[3] = col_type(x3, y3, z3, w3);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		col_type const & v0, 
-		col_type const & v1, 
+		col_type const & v0,
+		col_type const & v1,
 		col_type const & v2,
 		col_type const & v3
 	)
@@ -148,11 +148,11 @@ namespace detail
 		this->value[3] = v3;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat4x4<U> const & m
+		tmat4x4<U, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0]);
@@ -163,9 +163,9 @@ namespace detail
 
 	//////////////////////////////////////
 	// Convertion constructors
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_DECL tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_DECL tmat4x4<T, P>::tmat4x4
 	(
 		U const & s
 	)
@@ -173,23 +173,23 @@ namespace detail
 		GLM_STATIC_ASSERT(detail::type<U>::is_float || std::numeric_limits<U>::is_integer, "*mat4x4 constructor only takes float and integer types");
 
 		value_type const Zero(0);
-		this->value[0] = tvec4<T>(value_type(s), Zero, Zero, Zero);
-		this->value[1] = tvec4<T>(Zero, value_type(s), Zero, Zero);
-		this->value[2] = tvec4<T>(Zero, Zero, value_type(s), Zero);
-		this->value[3] = tvec4<T>(Zero, Zero, Zero, value_type(s));
+		this->value[0] = tvec4<T, P>(value_type(s), Zero, Zero, Zero);
+		this->value[1] = tvec4<T, P>(Zero, value_type(s), Zero, Zero);
+		this->value[2] = tvec4<T, P>(Zero, Zero, value_type(s), Zero);
+		this->value[3] = tvec4<T, P>(Zero, Zero, Zero, value_type(s));
 	}
 	
-	template <typename T> 
+	template <typename T, precision P> 
 	template <
-		typename X1, typename Y1, typename Z1, typename W1, 
-		typename X2, typename Y2, typename Z2, typename W2, 
-		typename X3, typename Y3, typename Z3, typename W3, 
-		typename X4, typename Y4, typename Z4, typename W4>  
-	GLM_FUNC_DECL tmat4x4<T>::tmat4x4
-	(
-		X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1, 
-		X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2, 
-		X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3, 
+		typename X1, typename Y1, typename Z1, typename W1,
+		typename X2, typename Y2, typename Z2, typename W2,
+		typename X3, typename Y3, typename Z3, typename W3,
+		typename X4, typename Y4, typename Z4, typename W4>
+	GLM_FUNC_DECL tmat4x4<T, P>::tmat4x4
+	(
+		X1 const & x1, Y1 const & y1, Z1 const & z1, W1 const & w1,
+		X2 const & x2, Y2 const & y2, Z2 const & z2, W2 const & w2,
+		X3 const & x3, Y3 const & y3, Z3 const & z3, W3 const & w3,
 		X4 const & x4, Y4 const & y4, Z4 const & z4, W4 const & w4
 	)
 	{
@@ -219,14 +219,14 @@ namespace detail
 		this->value[3] = col_type(value_type(x4), value_type(y4), value_type(z4), value_type(w4));
 	}
 	
-	template <typename T> 
-	template <typename V1, typename V2, typename V3, typename V4> 
-	GLM_FUNC_DECL tmat4x4<T>::tmat4x4
-	(
-		tvec4<V1> const & v1, 
-		tvec4<V2> const & v2, 
-		tvec4<V3> const & v3,
-		tvec4<V4> const & v4
+	template <typename T, precision P>
+	template <typename V1, typename V2, typename V3, typename V4>
+	GLM_FUNC_DECL tmat4x4<T, P>::tmat4x4
+	(
+		tvec4<V1, P> const & v1,
+		tvec4<V2, P> const & v2,
+		tvec4<V3, P> const & v3,
+		tvec4<V4, P> const & v4
 	)		
 	{
 		GLM_STATIC_ASSERT(detail::type<V1>::is_float || std::numeric_limits<V1>::is_integer, "*mat4x4 constructor only takes float and integer types, 1st parameter type invalid.");
@@ -242,22 +242,22 @@ namespace detail
 
 	//////////////////////////////////////
 	// Matrix convertion constructors
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat2x2<T> const & m
+		tmat2x2<T, P> const & m
 	)
 	{
-		this->value[0] = col_type(m[0], detail::tvec2<T>(0));
-		this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
+		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
 		this->value[2] = col_type(value_type(0));
 		this->value[3] = col_type(value_type(0), value_type(0), value_type(0), value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], value_type(0));
@@ -266,10 +266,10 @@ namespace detail
 		this->value[3] = col_type(value_type(0), value_type(0), value_type(0), value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat2x3<T> const & m
+		tmat2x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], value_type(0));
@@ -278,22 +278,22 @@ namespace detail
 		this->value[3] = col_type(value_type(0), value_type(0), value_type(0), value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat3x2<T> const & m
+		tmat3x2<T, P> const & m
 	)
 	{
-		this->value[0] = col_type(m[0], detail::tvec2<T>(0));
-		this->value[1] = col_type(m[1], detail::tvec2<T>(0));
-		this->value[2] = col_type(m[2], detail::tvec2<T>(0));
+		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
+		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
+		this->value[2] = col_type(m[2], detail::tvec2<T, P>(0));
 		this->value[3] = col_type(value_type(0), value_type(0), value_type(0), value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -302,22 +302,22 @@ namespace detail
 		this->value[3] = col_type(T(0), T(0), T(0), T(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat4x2<T> const & m
+		tmat4x2<T, P> const & m
 	)
 	{
-		this->value[0] = col_type(m[0], detail::tvec2<T>(0));
-		this->value[1] = col_type(m[1], detail::tvec2<T>(0));
+		this->value[0] = col_type(m[0], detail::tvec2<T, P>(0));
+		this->value[1] = col_type(m[1], detail::tvec2<T, P>(0));
 		this->value[2] = col_type(T(0));
 		this->value[3] = col_type(T(0), T(0), T(0), T(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		this->value[0] = m[0];
@@ -326,10 +326,10 @@ namespace detail
 		this->value[3] = col_type(T(0), T(0), T(0), T(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>::tmat4x4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>::tmat4x4
 	(
-		tmat4x3<T> const & m
+		tmat4x3<T, P> const & m
 	)
 	{
 		this->value[0] = col_type(m[0], T(0));
@@ -341,10 +341,10 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// Operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>& tmat4x4<T>::operator= 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>& tmat4x4<T, P>::operator=
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		//memcpy could be faster
@@ -356,11 +356,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>& tmat4x4<T>::operator= 
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>& tmat4x4<T, P>::operator=
 	(
-		tmat4x4<U> const & m
+		tmat4x4<U, P> const & m
 	)
 	{
 		//memcpy could be faster
@@ -372,9 +372,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>& tmat4x4<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>& tmat4x4<T, P>::operator+=
 	(
 		U const & s
 	)
@@ -386,11 +386,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x4<T>& tmat4x4<T>::operator+= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P>& tmat4x4<T, P>::operator+=
 	(
-		tmat4x4<U> const & m
+		tmat4x4<U, P> const & m
 	)
 	{
 		this->value[0] += m[0];
@@ -400,9 +400,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator-= 
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator-=
 	(
 		U const & s
 	)
@@ -414,11 +414,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	template <typename U>
-	GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator-= 
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator-=
 	(
-		tmat4x4<U> const & m
+		tmat4x4<U, P> const & m
 	)
 	{
 		this->value[0] -= m[0];
@@ -428,9 +428,9 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	template <typename U>
-	GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator*= 
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator*=
 	(
 		U const & s
 	)
@@ -442,19 +442,19 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	template <typename U>
-	GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator*= 
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator*=
 	(
-		tmat4x4<U> const & m
+		tmat4x4<U, P> const & m
 	)
 	{
 		return (*this = *this * m);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	template <typename U>
-	GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator/= 
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator/=
 	(
 		U const & s
 	)
@@ -466,18 +466,18 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	template <typename U>
-	GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator/= 
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator/=
 	(
-		tmat4x4<U> const & m
+		tmat4x4<U, P> const & m
 	)
 	{
 		return (*this = *this / m);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator++ ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator++ ()
 	{
 		++this->value[0];
 		++this->value[1];
@@ -486,8 +486,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> & tmat4x4<T>::operator-- ()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> & tmat4x4<T, P>::operator-- ()
 	{
 		--this->value[0];
 		--this->value[1];
@@ -496,8 +496,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> tmat4x4<T>::_inverse() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> tmat4x4<T, P>::_inverse() const
 	{
 		// Calculate all mat2 determinants
 		value_type SubFactor00 = this->value[2][2] * this->value[3][3] - this->value[3][2] * this->value[2][3];
@@ -520,7 +520,7 @@ namespace detail
 		value_type SubFactor17 = this->value[1][0] * this->value[2][2] - this->value[2][0] * this->value[1][2];
 		value_type SubFactor18 = this->value[1][0] * this->value[2][1] - this->value[2][0] * this->value[1][1];
 /*
-		tmat4x4<T> Inverse(
+		tmat4x4<T, P> Inverse(
 			+ (this->value[1][1] * SubFactor00 - this->value[1][2] * SubFactor01 + this->value[1][3] * SubFactor02),
 			- (this->value[1][0] * SubFactor00 - this->value[1][2] * SubFactor03 + this->value[1][3] * SubFactor04),
 			+ (this->value[1][0] * SubFactor01 - this->value[1][1] * SubFactor03 + this->value[1][3] * SubFactor05),
@@ -541,7 +541,7 @@ namespace detail
 			- (this->value[0][0] * SubFactor14 - this->value[0][1] * SubFactor16 + this->value[0][3] * SubFactor18),
 			+ (this->value[0][0] * SubFactor15 - this->value[0][1] * SubFactor17 + this->value[0][2] * SubFactor18));
 */
-		tmat4x4<T> Inverse(
+		tmat4x4<T, P> Inverse(
 			+ this->value[1][1] * SubFactor00 - this->value[1][2] * SubFactor01 + this->value[1][3] * SubFactor02,
 			- this->value[1][0] * SubFactor00 + this->value[1][2] * SubFactor03 - this->value[1][3] * SubFactor04,
 			+ this->value[1][0] * SubFactor01 - this->value[1][1] * SubFactor03 + this->value[1][3] * SubFactor05,
@@ -562,10 +562,10 @@ namespace detail
 			- this->value[0][0] * SubFactor14 + this->value[0][1] * SubFactor16 - this->value[0][3] * SubFactor18,
 			+ this->value[0][0] * SubFactor15 - this->value[0][1] * SubFactor17 + this->value[0][2] * SubFactor18);
 
-		value_type Determinant = 
-			+ this->value[0][0] * Inverse[0][0] 
-			+ this->value[0][1] * Inverse[1][0] 
-			+ this->value[0][2] * Inverse[2][0] 
+		value_type Determinant =
+			+ this->value[0][0] * Inverse[0][0]
+			+ this->value[0][1] * Inverse[1][0]
+			+ this->value[0][2] * Inverse[2][0]
 			+ this->value[0][3] * Inverse[3][0];
 
 		Inverse /= Determinant;
@@ -573,154 +573,154 @@ namespace detail
 	}
 
 	// Binary operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator+
 	(
-		tmat4x4<T> const & m, 
-		typename tmat4x4<T>::value_type const & s
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::value_type const & s
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			m[0] + s,
 			m[1] + s,
 			m[2] + s,
 			m[3] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator+
 	(
-		typename tmat4x4<T>::value_type const & s, 
-		tmat4x4<T> const & m
+		typename tmat4x4<T, P>::value_type const & s,
+		tmat4x4<T, P> const & m
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			m[0] + s,
 			m[1] + s,
 			m[2] + s,
 			m[3] + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator+
 	(
-		tmat4x4<T> const & m1, 
-		tmat4x4<T> const & m2
+		tmat4x4<T, P> const & m1,
+		tmat4x4<T, P> const & m2
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			m1[0] + m2[0],
 			m1[1] + m2[1],
 			m1[2] + m2[2],
 			m1[3] + m2[3]);
 	}
-    
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator- 
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator-
 	(
-		tmat4x4<T> const & m, 
-		typename tmat4x4<T>::value_type const & s
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::value_type const & s
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			m[0] - s,
 			m[1] - s,
 			m[2] - s,
 			m[3] - s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator-
 	(
-		typename tmat4x4<T>::value_type const & s, 
-		tmat4x4<T> const & m
+		typename tmat4x4<T, P>::value_type const & s,
+		tmat4x4<T, P> const & m
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			s - m[0],
 			s - m[1],
 			s - m[2],
 			s - m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator-
 	(
-		tmat4x4<T> const & m1, 
-		tmat4x4<T> const & m2
+		tmat4x4<T, P> const & m1,
+		tmat4x4<T, P> const & m2
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			m1[0] - m2[0],
 			m1[1] - m2[1],
 			m1[2] - m2[2],
 			m1[3] - m2[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator*
 	(
-		tmat4x4<T> const & m, 
-		typename tmat4x4<T>::value_type const  & s
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::value_type const  & s
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s,
 			m[3] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator*
 	(
-		typename tmat4x4<T>::value_type const & s, 
-		tmat4x4<T> const & m
+		typename tmat4x4<T, P>::value_type const & s,
+		tmat4x4<T, P> const & m
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			m[0] * s,
 			m[1] * s,
 			m[2] * s,
 			m[3] * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat4x4<T>::col_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::col_type operator*
 	(
-		tmat4x4<T> const & m, 
-		typename tmat4x4<T>::row_type const & v
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::row_type const & v
 	)
 	{
-		return typename tmat4x4<T>::col_type(
+		return typename tmat4x4<T, P>::col_type(
 			m[0][0] * v.x + m[1][0] * v.y + m[2][0] * v.z + m[3][0] * v.w,
 			m[0][1] * v.x + m[1][1] * v.y + m[2][1] * v.z + m[3][1] * v.w,
 			m[0][2] * v.x + m[1][2] * v.y + m[2][2] * v.z + m[3][2] * v.w,
 			m[0][3] * v.x + m[1][3] * v.y + m[2][3] * v.z + m[3][3] * v.w);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat4x4<T>::row_type operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::row_type operator*
 	(
-		typename tmat4x4<T>::col_type const & v, 
-		tmat4x4<T> const & m
+		typename tmat4x4<T, P>::col_type const & v,
+		tmat4x4<T, P> const & m
 	)
 	{
-		return typename tmat4x4<T>::row_type(
+		return typename tmat4x4<T, P>::row_type(
 			m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w,
 			m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
 			m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
 			m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat2x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat2x4<T, P> operator*
 	(
-		tmat4x4<T> const & m1, 
-		tmat2x4<T> const & m2
+		tmat4x4<T, P> const & m1,
+		tmat2x4<T, P> const & m2
 	)
 	{
-		return tmat2x4<T>(
+		return tmat2x4<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3],
@@ -731,14 +731,14 @@ namespace detail
 			m1[0][3] * m2[1][0] + m1[1][3] * m2[1][1] + m1[2][3] * m2[1][2] + m1[3][3] * m2[1][3]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tmat3x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat3x4<T, P> operator*
 	(
-		tmat4x4<T> const & m1, 
-		tmat3x4<T> const & m2
+		tmat4x4<T, P> const & m1,
+		tmat3x4<T, P> const & m2
 	)
 	{
-		return tmat3x4<T>(
+		return tmat3x4<T, P>(
 			m1[0][0] * m2[0][0] + m1[1][0] * m2[0][1] + m1[2][0] * m2[0][2] + m1[3][0] * m2[0][3],
 			m1[0][1] * m2[0][0] + m1[1][1] * m2[0][1] + m1[2][1] * m2[0][2] + m1[3][1] * m2[0][3],
 			m1[0][2] * m2[0][0] + m1[1][2] * m2[0][1] + m1[2][2] * m2[0][2] + m1[3][2] * m2[0][3],
@@ -753,24 +753,24 @@ namespace detail
 			m1[0][3] * m2[2][0] + m1[1][3] * m2[2][1] + m1[2][3] * m2[2][2] + m1[3][3] * m2[2][3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator*
 	(
-		tmat4x4<T> const & m1, 
-		tmat4x4<T> const & m2
+		tmat4x4<T, P> const & m1,
+		tmat4x4<T, P> const & m2
 	)
 	{
-		typename tmat4x4<T>::col_type const SrcA0 = m1[0];
-		typename tmat4x4<T>::col_type const SrcA1 = m1[1];
-		typename tmat4x4<T>::col_type const SrcA2 = m1[2];
-		typename tmat4x4<T>::col_type const SrcA3 = m1[3];
+		typename tmat4x4<T, P>::col_type const SrcA0 = m1[0];
+		typename tmat4x4<T, P>::col_type const SrcA1 = m1[1];
+		typename tmat4x4<T, P>::col_type const SrcA2 = m1[2];
+		typename tmat4x4<T, P>::col_type const SrcA3 = m1[3];
 
-		typename tmat4x4<T>::col_type const SrcB0 = m2[0];
-		typename tmat4x4<T>::col_type const SrcB1 = m2[1];
-		typename tmat4x4<T>::col_type const SrcB2 = m2[2];
-		typename tmat4x4<T>::col_type const SrcB3 = m2[3];
+		typename tmat4x4<T, P>::col_type const SrcB0 = m2[0];
+		typename tmat4x4<T, P>::col_type const SrcB1 = m2[1];
+		typename tmat4x4<T, P>::col_type const SrcB2 = m2[2];
+		typename tmat4x4<T, P>::col_type const SrcB3 = m2[3];
 
-		tmat4x4<T> Result(tmat4x4<T>::null);
+		tmat4x4<T, P> Result(tmat4x4<T, P>::null);
 		Result[0] = SrcA0 * SrcB0[0] + SrcA1 * SrcB0[1] + SrcA2 * SrcB0[2] + SrcA3 * SrcB0[3];
 		Result[1] = SrcA0 * SrcB1[0] + SrcA1 * SrcB1[1] + SrcA2 * SrcB1[2] + SrcA3 * SrcB1[3];
 		Result[2] = SrcA0 * SrcB2[0] + SrcA1 * SrcB2[1] + SrcA2 * SrcB2[2] + SrcA3 * SrcB2[3];
@@ -778,124 +778,124 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator/
 	(
-		tmat4x4<T> const & m, 
-		typename tmat4x4<T>::value_type const & s
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::value_type const & s
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			m[0] / s,
 			m[1] / s,
 			m[2] / s,
 			m[3] / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator/
 	(
-		typename tmat4x4<T>::value_type const & s, 
-		tmat4x4<T> const & m
+		typename tmat4x4<T, P>::value_type const & s,
+		tmat4x4<T, P> const & m
 	)
 	{
-		return tmat4x4<T>(
+		return tmat4x4<T, P>(
 			s / m[0],
 			s / m[1],
 			s / m[2],
 			s / m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat4x4<T>::col_type operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::col_type operator/
 	(
-		tmat4x4<T> const & m, 
-		typename tmat4x4<T>::row_type const & v
+		tmat4x4<T, P> const & m,
+		typename tmat4x4<T, P>::row_type const & v
 	)
 	{
 		return m._inverse() * v;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tmat4x4<T>::row_type operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tmat4x4<T, P>::row_type operator/
 	(
-		typename tmat4x4<T>::col_type const & v, 
-		tmat4x4<T> const & m
+		typename tmat4x4<T, P>::col_type const & v,
+		tmat4x4<T, P> const & m
 	)
 	{
 		return v * m._inverse();
 	}
  
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> operator/
 	(
-		tmat4x4<T> const & m1, 
-		tmat4x4<T> const & m2
+		tmat4x4<T, P> const & m1,
+		tmat4x4<T, P> const & m2
 	)
 	{
 		return m1 * m2._inverse();
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> const operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> const operator-
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
-		return tmat4x4<T>(
-			-m[0], 
+		return tmat4x4<T, P>(
+			-m[0],
 			-m[1],
 			-m[2],
 			-m[3]);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> const operator++ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> const operator++
 	(
-		tmat4x4<T> const & m, 
+		tmat4x4<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat4x4<T>(
-			m[0] + typename tmat4x4<T>::value_type(1),
-			m[1] + typename tmat4x4<T>::value_type(1),
-			m[2] + typename tmat4x4<T>::value_type(1),
-			m[3] + typename tmat4x4<T>::value_type(1));
+		return tmat4x4<T, P>(
+			m[0] + typename tmat4x4<T, P>::value_type(1),
+			m[1] + typename tmat4x4<T, P>::value_type(1),
+			m[2] + typename tmat4x4<T, P>::value_type(1),
+			m[3] + typename tmat4x4<T, P>::value_type(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tmat4x4<T> const operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tmat4x4<T, P> const operator--
 	(
-		tmat4x4<T> const & m, 
+		tmat4x4<T, P> const & m,
 		int
-	) 
+	)
 	{
-		return tmat4x4<T>(
-			m[0] - typename tmat4x4<T>::value_type(1),
-			m[1] - typename tmat4x4<T>::value_type(1),
-			m[2] - typename tmat4x4<T>::value_type(1),
-			m[3] - typename tmat4x4<T>::value_type(1));
+		return tmat4x4<T, P>(
+			m[0] - typename tmat4x4<T, P>::value_type(1),
+			m[1] - typename tmat4x4<T, P>::value_type(1),
+			m[2] - typename tmat4x4<T, P>::value_type(1),
+			m[3] - typename tmat4x4<T, P>::value_type(1));
 	}
 
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tmat4x4<T> const & m1, 
-		tmat4x4<T> const & m2
+		tmat4x4<T, P> const & m1,
+		tmat4x4<T, P> const & m2
 	)
 	{
 		return (m1[0] == m2[0]) && (m1[1] == m2[1]) && (m1[2] == m2[2]) && (m1[3] == m2[3]);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tmat4x4<T> const & m1, 
-		tmat4x4<T> const & m2
+		tmat4x4<T, P> const & m1,
+		tmat4x4<T, P> const & m2
 	)
 	{
 		return (m1[0] != m2[0]) || (m1[1] != m2[1]) || (m1[2] != m2[2]) || (m1[3] != m2[3]);

+ 57 - 55
glm/core/type_vec.hpp

@@ -29,13 +29,15 @@
 #ifndef glm_core_type_vec
 #define glm_core_type_vec
 
+#include "precision.hpp"
+
 namespace glm{
 namespace detail
 {
-	template <typename T> struct tvec1;
-	template <typename T> struct tvec2;
-	template <typename T> struct tvec3;
-	template <typename T> struct tvec4;
+	template <typename T, precision P> struct tvec1;
+	template <typename T, precision P> struct tvec2;
+	template <typename T, precision P> struct tvec3;
+	template <typename T, precision P> struct tvec4;
 	
 	template <typename T>
 	struct is_vector
@@ -47,27 +49,27 @@ namespace detail
 		};
 	};
 	
-#	define GLM_DETAIL_IS_VECTOR(TYPE)	\
-		template <typename T>			\
-		struct is_vector<TYPE<T> >		\
-		{								\
-			enum is_vector_enum			\
-			{							\
-				_YES = 1,				\
-				_NO = 0					\
-			};							\
+#	define GLM_DETAIL_IS_VECTOR(TYPE)		\
+		template <typename T, precision P>	\
+		struct is_vector<TYPE<T, P> >		\
+		{									\
+			enum is_vector_enum				\
+			{								\
+				_YES = 1,					\
+				_NO = 0						\
+			};								\
 		}
 }//namespace detail
 	
-	typedef detail::tvec1<highp_float>		highp_vec1_t;
-	typedef detail::tvec1<mediump_float>	mediump_vec1_t;
-	typedef detail::tvec1<lowp_float>		lowp_vec1_t;
-	typedef detail::tvec1<highp_int>		highp_ivec1_t;
-	typedef detail::tvec1<mediump_int>		mediump_ivec1_t;
-	typedef detail::tvec1<lowp_int>			lowp_ivec1_t;
-	typedef detail::tvec1<highp_uint>		highp_uvec1_t;
-	typedef detail::tvec1<mediump_uint>		mediump_uvec1_t;
-	typedef detail::tvec1<lowp_uint>		lowp_uvec1_t;
+	typedef detail::tvec1<float, highp>		highp_vec1_t;
+	typedef detail::tvec1<float, mediump>	mediump_vec1_t;
+	typedef detail::tvec1<float, lowp>		lowp_vec1_t;
+	typedef detail::tvec1<int, highp>		highp_ivec1_t;
+	typedef detail::tvec1<int, mediump>		mediump_ivec1_t;
+	typedef detail::tvec1<int, lowp>		lowp_ivec1_t;
+	typedef detail::tvec1<uint, highp>		highp_uvec1_t;
+	typedef detail::tvec1<uint, mediump>	mediump_uvec1_t;
+	typedef detail::tvec1<uint, lowp>		lowp_uvec1_t;
 	
 	/// @addtogroup core_precision
 	/// @{
@@ -77,63 +79,63 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec2<highp_float>		highp_vec2;
+	typedef detail::tvec2<float, highp>		highp_vec2;
 	
 	/// 2 components vector of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec2<mediump_float>	mediump_vec2;
+	typedef detail::tvec2<float, mediump>	mediump_vec2;
 	
 	/// 2 components vector of low precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec2<lowp_float>		lowp_vec2;
+	typedef detail::tvec2<float, lowp>		lowp_vec2;
 	
 	/// 2 components vector of high precision signed integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec2<highp_int>		highp_ivec2;
+	typedef detail::tvec2<int, highp>		highp_ivec2;
 	
 	/// 2 components vector of medium precision signed integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec2<mediump_int>		mediump_ivec2;
+	typedef detail::tvec2<int, mediump>		mediump_ivec2;
 	
 	/// 2 components vector of low precision signed integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec2<lowp_int>			lowp_ivec2;
+	typedef detail::tvec2<int, lowp>		lowp_ivec2;
 	
 	/// 2 components vector of high precision unsigned integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec2<highp_uint>		highp_uvec2;
+	typedef detail::tvec2<uint, highp>		highp_uvec2;
 	
 	/// 2 components vector of medium precision unsigned integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec2<mediump_uint>		mediump_uvec2;
+	typedef detail::tvec2<uint, mediump>	mediump_uvec2;
 	
 	/// 2 components vector of low precision unsigned integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec2<lowp_uint>		lowp_uvec2;
+	typedef detail::tvec2<uint, lowp>		lowp_uvec2;
 	
 	/// @}
 	
@@ -146,63 +148,63 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec3<highp_float>		highp_vec3;
+	typedef detail::tvec3<float, highp>		highp_vec3;
 	
 	/// 3 components vector of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec3<mediump_float>	mediump_vec3;
+	typedef detail::tvec3<float, mediump>	mediump_vec3;
 	
 	/// 3 components vector of low precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec3<lowp_float>		lowp_vec3;
+	typedef detail::tvec3<float, lowp>		lowp_vec3;
 	
 	/// 3 components vector of high precision signed integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec3<highp_int>		highp_ivec3;
+	typedef detail::tvec3<int, highp>		highp_ivec3;
 	
 	/// 3 components vector of medium precision signed integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec3<mediump_int>		mediump_ivec3;
+	typedef detail::tvec3<int, mediump>		mediump_ivec3;
 	
 	/// 3 components vector of low precision signed integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec3<lowp_int>			lowp_ivec3;
+	typedef detail::tvec3<int, lowp>		lowp_ivec3;
 	
 	/// 3 components vector of high precision unsigned integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec3<highp_uint>		highp_uvec3;
+	typedef detail::tvec3<uint, highp>		highp_uvec3;
 	
 	/// 3 components vector of medium precision unsigned integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec3<mediump_uint>		mediump_uvec3;
+	typedef detail::tvec3<uint, mediump>	mediump_uvec3;
 	
 	/// 3 components vector of low precision unsigned integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec3<lowp_uint>		lowp_uvec3;
+	typedef detail::tvec3<uint, lowp>		lowp_uvec3;
 	
 	/// @}
 	
@@ -214,63 +216,63 @@ namespace detail
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec4<highp_float>		highp_vec4;
+	typedef detail::tvec4<float, highp>		highp_vec4;
 	
 	/// 4 components vector of medium precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec4<mediump_float>	mediump_vec4;
+	typedef detail::tvec4<float, mediump>	mediump_vec4;
 	
 	/// 4 components vector of low precision floating-point numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec4<lowp_float>		lowp_vec4;
+	typedef detail::tvec4<float, lowp>		lowp_vec4;
 	
 	/// 4 components vector of high precision signed integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec4<highp_int>		highp_ivec4;
+	typedef detail::tvec4<int, highp>		highp_ivec4;
 	
 	/// 4 components vector of medium precision signed integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec4<mediump_int>		mediump_ivec4;
+	typedef detail::tvec4<int, mediump>		mediump_ivec4;
 	
 	/// 4 components vector of low precision signed integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec4<lowp_int>			lowp_ivec4;
+	typedef detail::tvec4<int, lowp>		lowp_ivec4;
 	
 	/// 4 components vector of high precision unsigned integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec4<highp_uint>		highp_uvec4;
+	typedef detail::tvec4<uint, highp>		highp_uvec4;
 	
 	/// 4 components vector of medium precision unsigned integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec4<mediump_uint>		mediump_uvec4;
+	typedef detail::tvec4<uint, mediump>	mediump_uvec4;
 	
 	/// 4 components vector of low precision unsigned integer numbers.
 	/// There is no guarantee on the actual precision.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
 	/// @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::tvec4<lowp_uint>		lowp_uvec4;
+	typedef detail::tvec4<uint, lowp>		lowp_uvec4;
 	
 	/// @}
 	
@@ -379,17 +381,17 @@ namespace detail
 	//! 2 components vector of boolean.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
-	typedef detail::tvec2<bool>		bvec2;
+	typedef detail::tvec2<bool, mediump>		bvec2;
 	
 	//! 3 components vector of boolean.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
-	typedef detail::tvec3<bool>		bvec3;
+	typedef detail::tvec3<bool, mediump>		bvec3;
 	
 	//! 4 components vector of boolean.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
-	typedef detail::tvec4<bool>		bvec4;
+	typedef detail::tvec4<bool, mediump>		bvec4;
 	
 	//////////////////////////
 	// Double definition
@@ -397,17 +399,17 @@ namespace detail
 	//! Vector of 2 double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
-	typedef detail::tvec2<double>	dvec2;
+	typedef detail::tvec2<double, mediump>		dvec2;
 	
 	//! Vector of 3 double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
-	typedef detail::tvec3<double>	dvec3;
+	typedef detail::tvec3<double, mediump>		dvec3;
 	
 	//! Vector of 4 double-precision floating-point numbers.
 	///
 	/// @see <a href="http://www.opengl.org/registry/doc/GLSLangSpec.4.20.8.pdf">GLSL 4.20.8 specification, section 4.1.5 Vectors</a>
-	typedef detail::tvec4<double>	dvec4;
+	typedef detail::tvec4<double, mediump>		dvec4;
 	
 	/// @}
 }//namespace glm

+ 41 - 47
glm/core/type_vec1.hpp

@@ -36,20 +36,15 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> struct tref1;
-	template <typename T> struct tref2;
-	template <typename T> struct tref3;
-	template <typename T> struct tref4;
-
-	template <typename T>
+	template <typename T, precision P>
 	struct tvec1
 	{
 		enum ctor{null};
 
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec1<T> type;
-		typedef tvec1<bool> bool_type;
+		typedef tvec1<T, P> type;
+		typedef tvec1<bool, P> bool_type;
 
 		GLM_FUNC_DECL GLM_CONSTEXPR size_type length() const;
 
@@ -72,7 +67,7 @@ namespace detail
 		// Implicit basic constructors
 
 		GLM_FUNC_DECL tvec1();
-		GLM_FUNC_DECL tvec1(tvec1<T> const & v);
+		GLM_FUNC_DECL tvec1(tvec1<T, P> const & v);
 
 		//////////////////////////////////////
 		// Explicit basic constructors
@@ -85,7 +80,7 @@ namespace detail
 		//////////////////////////////////////
 		// Swizzle constructors
 
-		GLM_FUNC_DECL tvec1(tref1<T> const & r);
+		GLM_FUNC_DECL tvec1(tref1<T, P> const & r);
 
 		//////////////////////////////////////
 		// Convertion scalar constructors
@@ -99,87 +94,86 @@ namespace detail
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		GLM_FUNC_DECL explicit tvec1(tvec2<U> const & v);
+		GLM_FUNC_DECL explicit tvec1(tvec2<U, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		GLM_FUNC_DECL explicit tvec1(tvec3<U> const & v);
+		GLM_FUNC_DECL explicit tvec1(tvec3<U, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		GLM_FUNC_DECL explicit tvec1(tvec4<U> const & v);
+		GLM_FUNC_DECL explicit tvec1(tvec4<U, P> const & v);
 
 		//////////////////////////////////////
 		// Unary arithmetic operators
 
-		GLM_FUNC_DECL tvec1<T> & operator= (tvec1<T> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator= (tvec1<T, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator= (tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator= (tvec1<U, P> const & v);
 
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator+=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator+=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator+=(tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator+=(tvec1<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator-=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator-=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator-=(tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator-=(tvec1<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator*=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator*=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator*=(tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator*=(tvec1<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator/=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator/=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator/=(tvec1<U> const & v);
-		GLM_FUNC_DECL tvec1<T> & operator++();
-		GLM_FUNC_DECL tvec1<T> & operator--();
+		GLM_FUNC_DECL tvec1<T, P> & operator/=(tvec1<U, P> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator++();
+		GLM_FUNC_DECL tvec1<T, P> & operator--();
 
 		//////////////////////////////////////
 		// Unary bit operators
 
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator%=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator%=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator%=(tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator%=(tvec1<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator&=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator&=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator&=(tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator&=(tvec1<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator|=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator|=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator|=(tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator|=(tvec1<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator^=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator^=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator^=(tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator^=(tvec1<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator<<=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator<<=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator<<=(tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator<<=(tvec1<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator>>=(U const & s);
+		GLM_FUNC_DECL tvec1<T, P> & operator>>=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec1<T> & operator>>=(tvec1<U> const & v);
+		GLM_FUNC_DECL tvec1<T, P> & operator>>=(tvec1<U, P> const & v);
 
 		//////////////////////////////////////
 		// Swizzle operators
 
 		GLM_FUNC_DECL value_type swizzle(comp X) const;
-		GLM_FUNC_DECL tvec2<T> swizzle(comp X, comp Y) const;
-		GLM_FUNC_DECL tvec3<T> swizzle(comp X, comp Y, comp Z) const;
-		GLM_FUNC_DECL tvec4<T> swizzle(comp X, comp Y, comp Z, comp W) const;
-		GLM_FUNC_DECL tref1<T> swizzle(comp X);
+		GLM_FUNC_DECL tvec2<T, P> swizzle(comp X, comp Y) const;
+		GLM_FUNC_DECL tvec3<T, P> swizzle(comp X, comp Y, comp Z) const;
+		GLM_FUNC_DECL tvec4<T, P> swizzle(comp X, comp Y, comp Z, comp W) const;
+		GLM_FUNC_DECL tref1<T, P> swizzle(comp X);
 	};
 
-	template <typename T>
+	template <typename T, precision P>
 	struct tref1
 	{
 		GLM_FUNC_DECL tref1(T & x);
-		GLM_FUNC_DECL tref1(tref1<T> const & r);
-		GLM_FUNC_DECL tref1(tvec1<T> const & v);
-
-		GLM_FUNC_DECL tref1<T> & operator= (tref1<T> const & r);
-		GLM_FUNC_DECL tref1<T> & operator= (tvec1<T> const & v);
+		GLM_FUNC_DECL tref1(tref1<T, P> const & r);
+		GLM_FUNC_DECL tref1(tvec1<T, P> const & v);
+		GLM_FUNC_DECL tref1<T, P> & operator= (tref1<T, P> const & r);
+		GLM_FUNC_DECL tref1<T, P> & operator= (tvec1<T, P> const & v);
 
 		T& x;
 	};

+ 289 - 294
glm/core/type_vec1.inl

@@ -29,8 +29,8 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tvec1<T>::size_type tvec1<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tvec1<T, P>::size_type tvec1<T, P>::length() const
 	{
 		return 1;
 	}
@@ -38,8 +38,8 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tvec1<T>::value_type & tvec1<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tvec1<T, P>::value_type & tvec1<T, P>::operator[]
 	(
 		size_type i
 	)
@@ -48,8 +48,8 @@ namespace detail
 		return (&x)[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tvec1<T>::value_type const & tvec1<T>::operator[]
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tvec1<T, P>::value_type const & tvec1<T, P>::operator[]
 	(
 		size_type i
 	) const
@@ -61,22 +61,22 @@ namespace detail
 	//////////////////////////////////////
 	// Implicit basic constructors
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T>::tvec1() :
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1() :
 		x(value_type(0))
 	{}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1
 	(
 		ctor
 	)
 	{}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1
 	(
-		tvec1<T> const & v
+		tvec1<T, P> const & v
 	) :
 		x(v.x)
 	{}
@@ -84,8 +84,8 @@ namespace detail
 	//////////////////////////////////////
 	// Explicit basic constructors
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1
 	(
 		value_type const & s
 	) :
@@ -95,10 +95,10 @@ namespace detail
 	//////////////////////////////////////
 	// Swizzle constructors
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1
 	(
-		tref1<T> const & r
+		tref1<T, P> const & r
 	) :
 		x(r.x)
 	{}
@@ -106,9 +106,9 @@ namespace detail
 	//////////////////////////////////////
 	// Convertion scalar constructors
 		
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1
 	(
 		U const & s
 	) :
@@ -118,29 +118,29 @@ namespace detail
 	//////////////////////////////////////
 	// Convertion vector constructors
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1
 	(
-		tvec2<U> const & v
+		tvec2<U, P> const & v
 	) :
 		x(value_type(v.x))
 	{}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1
 	(
-		tvec3<U> const & v
+		tvec3<U, P> const & v
 	) :
 		x(value_type(v.x))
 	{}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T>::tvec1
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1
 	(
-		tvec4<U> const & v
+		tvec4<U, P> const & v
 	) :
 		x(value_type(v.x))
 	{}
@@ -148,30 +148,30 @@ namespace detail
 	//////////////////////////////////////
 	// Unary arithmetic operators
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator=
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator=
 	(
-		tvec1<T> const & v
+		tvec1<T, P> const & v
 	)
 	{
 		this->x = v.x;
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x = T(v.x);
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator+=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator+=
 	(
 		U const & s
 	)
@@ -180,20 +180,20 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator+=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator+=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x += T(v.x);
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator-=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator-=
 	(
 		U const & s
 	)
@@ -202,20 +202,20 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator-=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator-=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x -= T(v.x);
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator*=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator*=
 	(
 		U const & s
 	)
@@ -224,20 +224,20 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator*=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator*=
 	(	
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x *= T(v.x);
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator/=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator/=
 	(
 		U const & s
 	)
@@ -246,26 +246,26 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator/=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator/=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x /= T(v.x);
 		return *this;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator++()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator++()
 	{
 		++this->x;
 		return *this;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator--()
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator--()
 	{
 		--this->x;
 		return *this;
@@ -274,21 +274,21 @@ namespace detail
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P> 
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
 		return (v1.x == v2.x);
 	}
 
-	template <typename T> 
+	template <typename T, precision P> 
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
 		return (v1.x != v2.x);
@@ -297,9 +297,9 @@ namespace detail
 	//////////////////////////////////////
 	// Unary bit operators
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator%=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator%=
 	(
 		U const & s
 	)
@@ -308,20 +308,20 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator%=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator%=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x %= T(v.x);
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator&=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator&=
 	(
 		U const & s
 	)
@@ -330,20 +330,20 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator&=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator&=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x &= T(v.x);
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator|=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator|=
 	(
 		U const & s
 	)
@@ -352,20 +352,20 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator|=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator|=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x |= U(v.x);
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator^=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator^=
 	(
 		U const & s
 	)
@@ -374,20 +374,20 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator^=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator^=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x ^= T(v.x);
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator<<=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator<<=
 	(
 		U const & s
 	)
@@ -396,20 +396,20 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator<<=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator<<=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x <<= T(v.x);
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator>>=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator>>=
 	(
 		U const & s
 	)
@@ -418,11 +418,11 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec1<T> & tvec1<T>::operator>>=
+	GLM_FUNC_QUALIFIER tvec1<T, P> & tvec1<T, P>::operator>>=
 	(
-		tvec1<U> const & v
+		tvec1<U, P> const & v
 	)
 	{
 		this->x >>= T(v.x);
@@ -432,44 +432,40 @@ namespace detail
 	//////////////////////////////////////
 	// Swizzle operators
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER T 
-	tvec1<T>::swizzle(comp x) const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T tvec1<T, P>::swizzle(comp x) const
 	{
 		return (*this)[x];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec2<T> 
-	tvec1<T>::swizzle
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec2<T, P> tvec1<T, P>::swizzle
 	(
 		comp x, 
 		comp y
 	) const
 	{
-		return tvec2<T>(
+		return tvec2<T, P>(
 			(*this)[x],
 			(*this)[y]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec3<T> 
-	tvec1<T>::swizzle
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec3<T, P> tvec1<T, P>::swizzle
 	(
 		comp x, 
 		comp y, 
 		comp z
 	) const
 	{
-		return tvec3<T>(
+		return tvec3<T, P>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec4<T> 
-	tvec1<T>::swizzle
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec4<T, P> tvec1<T, P>::swizzle
 	(
 		comp x, 
 		comp y, 
@@ -477,447 +473,446 @@ namespace detail
 		comp w
 	) const
 	{
-		return tvec4<T>(
+		return tvec4<T, P>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z],
 			(*this)[w]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tref1<T> 
-	tvec1<T>::swizzle
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tref1<T, P> tvec1<T, P>::swizzle
 	(
 		comp x
 	)
 	{
-		return tref1<T>(
+		return tref1<T, P>(
 			(*this)[x]);
 	}
 
 	//////////////////////////////////////
 	// Binary arithmetic operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator+ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator+
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v,
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x + s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator+ 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator+ 
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s + v.x);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator+ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator+
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x + v2.x);
 	}
 
 	//operator-
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator- 
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator-
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v, 
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x - s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator-
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s - v.x);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator-
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x - v2.x);
 	}
 
 	//operator*
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator*
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v,
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator*
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s * v.x);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator*
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x * v2.x);
 	}
 
 	//operator/
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator/
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v,
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x / s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator/
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s / v.x);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator/
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x / v2.x);
 	}
 
 	// Unary constant operators
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator-
 	(
-		tvec1<T> const & v
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			-v.x);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator++ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator++
 	(
-		tvec1<T> const & v, 
+		tvec1<T, P> const & v,
 		int
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x + T(1));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator-- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator--
 	(
-		tvec1<T> const & v, 
+		tvec1<T, P> const & v,
 		int
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x - T(1));
 	}
 
 	//////////////////////////////////////
 	// Binary bit operators
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator% 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator%
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v,
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x % s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator% 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator%
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s % v.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator% 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator%
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x % v2.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator& 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator&
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v, 
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x & s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator& 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator&
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s & v.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator& 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator&
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x & v2.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator| 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator|
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v,
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x | s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator| 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator|
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s | v.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator| 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator|
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x | v2.x);
 	}
 		
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator^ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator^
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v,
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x ^ s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator^ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator^
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s ^ v.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator^ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator^
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x ^ v2.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator<< 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator<<
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v, 
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x << s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator<< 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator<<
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s << v.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator<< 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator<<
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x << v2.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator>> 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator>>
 	(
-		tvec1<T> const & v, 
-		typename tvec1<T>::value_type const & s
+		tvec1<T, P> const & v,
+		typename tvec1<T, P>::value_type const & s
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v.x >> s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator>> 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator>>
 	(
-		typename tvec1<T>::value_type const & s, 
-		tvec1<T> const & v
+		typename tvec1<T, P>::value_type const & s,
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			s >> v.x);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tvec1<T> operator>> 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator>>
 	(
-		tvec1<T> const & v1, 
-		tvec1<T> const & v2
+		tvec1<T, P> const & v1,
+		tvec1<T, P> const & v2
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			v1.x >> v2.x);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tvec1<T> operator~ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tvec1<T, P> operator~
 	(
-		tvec1<T> const & v
+		tvec1<T, P> const & v
 	)
 	{
-		return tvec1<T>(
+		return tvec1<T, P>(
 			~v.x);
 	}
 
 	//////////////////////////////////////
 	// tref definition
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tref1<T>::tref1
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tref1<T, P>::tref1
 	(
 		T & x
 	) :
 		x(x)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tref1<T>::tref1
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tref1<T, P>::tref1
 	(
-		tref1<T> const & r
+		tref1<T, P> const & r
 	) :
 		x(r.x)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tref1<T>::tref1
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tref1<T, P>::tref1
 	(
-		tvec1<T> const & v
+		tvec1<T, P> const & v
 	) :
 		x(v.x)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tref1<T> & tref1<T>::operator= 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tref1<T, P> & tref1<T, P>::operator=
 	(
-		tref1<T> const & r
+		tref1<T, P> const & r
 	)
 	{
 		x = r.x;
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tref1<T> & tref1<T>::operator= 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tref1<T, P> & tref1<T, P>::operator=
 	(
-		tvec1<T> const & v
+		tvec1<T, P> const & v
 	)
 	{
 		x = v.x;

+ 56 - 63
glm/core/type_vec2.hpp

@@ -36,20 +36,15 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> struct tref1;
-	template <typename T> struct tref2;
-	template <typename T> struct tref3;
-	template <typename T> struct tref4;
-	
-	template <typename T>
+	template <typename T, precision P>
 	struct tvec2
 	{
 		enum ctor{null};
 
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec2<T> type;
-		typedef tvec2<bool> bool_type;
+		typedef tvec2<T, P> type;
+		typedef tvec2<bool, P> bool_type;
 
 		GLM_FUNC_DECL GLM_CONSTEXPR size_type length() const;
 
@@ -60,15 +55,15 @@ namespace detail
 		union 
 		{
 #		if(defined(GLM_SWIZZLE))
-			_GLM_SWIZZLE2_2_MEMBERS(value_type, glm::detail::tvec2<value_type>, x, y)
-			_GLM_SWIZZLE2_2_MEMBERS(value_type, glm::detail::tvec2<value_type>, r, g)
-			_GLM_SWIZZLE2_2_MEMBERS(value_type, glm::detail::tvec2<value_type>, s, t)
-			_GLM_SWIZZLE2_3_MEMBERS(value_type, glm::detail::tvec3<value_type>, x, y)
-			_GLM_SWIZZLE2_3_MEMBERS(value_type, glm::detail::tvec3<value_type>, r, g)
-			_GLM_SWIZZLE2_3_MEMBERS(value_type, glm::detail::tvec3<value_type>, s, t)
-			_GLM_SWIZZLE2_4_MEMBERS(value_type, glm::detail::tvec4<value_type>, x, y)
-			_GLM_SWIZZLE2_4_MEMBERS(value_type, glm::detail::tvec4<value_type>, r, g)
-			_GLM_SWIZZLE2_4_MEMBERS(value_type, glm::detail::tvec4<value_type>, s, t)
+			_GLM_SWIZZLE2_2_MEMBERS(T, glm::detail::tvec2<T, P>, x, y)
+			_GLM_SWIZZLE2_2_MEMBERS(T, glm::detail::tvec2<T, P>, r, g)
+			_GLM_SWIZZLE2_2_MEMBERS(T, glm::detail::tvec2<T, P>, s, t)
+			_GLM_SWIZZLE2_3_MEMBERS(T, glm::detail::tvec3<T, P>, x, y)
+			_GLM_SWIZZLE2_3_MEMBERS(T, glm::detail::tvec3<T, P>, r, g)
+			_GLM_SWIZZLE2_3_MEMBERS(T, glm::detail::tvec3<T, P>, s, t)
+			_GLM_SWIZZLE2_4_MEMBERS(T, glm::detail::tvec4<T, P>, x, y)
+			_GLM_SWIZZLE2_4_MEMBERS(T, glm::detail::tvec4<T, P>, r, g)
+			_GLM_SWIZZLE2_4_MEMBERS(T, glm::detail::tvec4<T, P>, s, t)
 #		endif//(defined(GLM_SWIZZLE))
 
 			struct {value_type r, g;};
@@ -81,16 +76,16 @@ namespace detail
 
 #		if(defined(GLM_SWIZZLE))
 			// Defines all he swizzle operator as functions
-			GLM_SWIZZLE_GEN_REF_FROM_VEC2(value_type, detail::tvec2, detail::tref2)
-			GLM_SWIZZLE_GEN_VEC_FROM_VEC2(value_type, detail::tvec2, detail::tvec2, detail::tvec3, detail::tvec4)
+			GLM_SWIZZLE_GEN_REF_FROM_VEC2(value_type, P, detail::tvec2, detail::tref2)
+			GLM_SWIZZLE_GEN_VEC_FROM_VEC2(value_type, P, detail::tvec2, detail::tvec2, detail::tvec3, detail::tvec4)
 #		endif//(defined(GLM_SWIZZLE))
 #	else //(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW)
 		value_type x, y;
 
 #		if(defined(GLM_SWIZZLE))
 			// Defines all he swizzle operator as functions
-			GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(value_type, detail::tvec2, detail::tref2, x, y)
-			GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(value_type, detail::tvec2, detail::tvec2, detail::tvec3, detail::tvec4, x, y)
+			GLM_SWIZZLE_GEN_REF2_FROM_VEC2_SWIZZLE(value_type, P, detail::tvec2, detail::tref2, x, y)
+			GLM_SWIZZLE_GEN_VEC_FROM_VEC2_COMP(value_type, P, detail::tvec2, detail::tvec2, detail::tvec3, detail::tvec4, x, y)
 #		endif//(defined(GLM_SWIZZLE))
 #	endif//GLM_COMPONENT
 
@@ -104,7 +99,7 @@ namespace detail
 		// Implicit basic constructors
 
 		GLM_FUNC_DECL tvec2();
-		GLM_FUNC_DECL tvec2(tvec2<T> const & v);
+		GLM_FUNC_DECL tvec2(tvec2<T, P> const & v);
 
 		//////////////////////////////////////
 		// Explicit basic constructors
@@ -120,10 +115,10 @@ namespace detail
 		//////////////////////////////////////
 		// Swizzle constructors
 
-		tvec2(tref2<T> const & r);
+		tvec2(tref2<T, P> const & r);
 
 		template <int E0, int E1>
-		GLM_FUNC_DECL tvec2(const glm::detail::swizzle<2,T,tvec2<T>,E0,E1,-1,-2>& that)
+		GLM_FUNC_DECL tvec2(const glm::detail::swizzle<2,T,tvec2<T, P>,E0,E1,-1,-2>& that)
 		{
 			*this = that();
 		}
@@ -146,89 +141,87 @@ namespace detail
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		GLM_FUNC_DECL explicit tvec2(tvec2<U> const & v);
+		GLM_FUNC_DECL explicit tvec2(tvec2<U, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		GLM_FUNC_DECL explicit tvec2(tvec3<U> const & v);
+		GLM_FUNC_DECL explicit tvec2(tvec3<U, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		GLM_FUNC_DECL explicit tvec2(tvec4<U> const & v);
+		GLM_FUNC_DECL explicit tvec2(tvec4<U, P> const & v);
 
 		//////////////////////////////////////
 		// Unary arithmetic operators
 
-		GLM_FUNC_DECL tvec2<T> & operator= (tvec2<T> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator= (tvec2<T, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator= (tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator= (tvec2<U, P> const & v);
 
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator+=(U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator+=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator+=(tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator+=(tvec2<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator-=(U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator-=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator-=(tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator-=(tvec2<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator*=(U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator*=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator*=(tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator*=(tvec2<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator/=(U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator/=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator/=(tvec2<U> const & v);
-		GLM_FUNC_DECL tvec2<T> & operator++();
-		GLM_FUNC_DECL tvec2<T> & operator--();
+		GLM_FUNC_DECL tvec2<T, P> & operator/=(tvec2<U, P> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator++();
+		GLM_FUNC_DECL tvec2<T, P> & operator--();
 
 		//////////////////////////////////////
 		// Unary bit operators
 
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator%= (U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator%= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator%= (tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator%= (tvec2<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator&= (U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator&= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator&= (tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator&= (tvec2<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator|= (U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator|= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator|= (tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator|= (tvec2<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator^= (U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator^= (U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator^= (tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator^= (tvec2<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator<<=(U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator<<=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator<<=(tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator<<=(tvec2<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator>>=(U const & s);
+		GLM_FUNC_DECL tvec2<T, P> & operator>>=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec2<T> & operator>>=(tvec2<U> const & v);
+		GLM_FUNC_DECL tvec2<T, P> & operator>>=(tvec2<U, P> const & v);
 
 		//////////////////////////////////////
 		// Swizzle operators
 
 		GLM_FUNC_DECL value_type swizzle(comp X) const;
-		GLM_FUNC_DECL tvec2<T> swizzle(comp X, comp Y) const;
-		GLM_FUNC_DECL tvec3<T> swizzle(comp X, comp Y, comp Z) const;
-		GLM_FUNC_DECL tvec4<T> swizzle(comp X, comp Y, comp Z, comp W) const;
-		GLM_FUNC_DECL tref2<T> swizzle(comp X, comp Y);
+		GLM_FUNC_DECL tvec2<T, P> swizzle(comp X, comp Y) const;
+		GLM_FUNC_DECL tvec3<T, P> swizzle(comp X, comp Y, comp Z) const;
+		GLM_FUNC_DECL tvec4<T, P> swizzle(comp X, comp Y, comp Z, comp W) const;
+		GLM_FUNC_DECL tref2<T, P> swizzle(comp X, comp Y);
 	};
 
-	template <typename T>
+	template <typename T, precision P>
 	struct tref2
 	{
 		GLM_FUNC_DECL tref2(T & x, T & y);
-		GLM_FUNC_DECL tref2(tref2<T> const & r);
-		GLM_FUNC_DECL explicit tref2(tvec2<T> const & v);
-
-		GLM_FUNC_DECL tref2<T> & operator= (tref2<T> const & r);
-		GLM_FUNC_DECL tref2<T> & operator= (tvec2<T> const & v);
-
-		GLM_FUNC_DECL tvec2<T> operator() ();
+		GLM_FUNC_DECL tref2(tref2<T, P> const & r);
+		GLM_FUNC_DECL explicit tref2(tvec2<T, P> const & v);
+		GLM_FUNC_DECL tref2<T, P> & operator= (tref2<T, P> const & r);
+		GLM_FUNC_DECL tref2<T, P> & operator= (tvec2<T, P> const & v);
+		GLM_FUNC_DECL tvec2<T, P> operator() ();
 
 		T & x;
 		T & y;

文件差异内容过多而无法显示
+ 304 - 312
glm/core/type_vec2.inl


+ 62 - 69
glm/core/type_vec3.hpp

@@ -36,20 +36,15 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> struct tref1;
-	template <typename T> struct tref2;
-	template <typename T> struct tref3;
-	template <typename T> struct tref4;
-
-	template <typename T>
+	template <typename T, precision P>
 	struct tvec3
 	{	
 		enum ctor{null};
 
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec3<T> type;
-		typedef tvec3<bool> bool_type;
+		typedef tvec3<T, P> type;
+		typedef tvec3<bool, P> bool_type;
 
 		GLM_FUNC_DECL GLM_CONSTEXPR size_type length() const;
 
@@ -82,16 +77,16 @@ namespace detail
 
 #		if(defined(GLM_SWIZZLE))
 			// Defines all he swizzle operator as functions
-			GLM_SWIZZLE_GEN_REF_FROM_VEC3(T, detail::tvec3, detail::tref2, detail::tref3)
-			GLM_SWIZZLE_GEN_VEC_FROM_VEC3(T, detail::tvec3, detail::tvec2, detail::tvec3, detail::tvec4)
+			GLM_SWIZZLE_GEN_REF_FROM_VEC3(T, P, detail::tvec3, detail::tref2, detail::tref3)
+			GLM_SWIZZLE_GEN_VEC_FROM_VEC3(T, P, detail::tvec3, detail::tvec2, detail::tvec3, detail::tvec4)
 #		endif//(defined(GLM_SWIZZLE))
 #	else //(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW)
 		value_type x, y, z;
 
 #		if(defined(GLM_SWIZZLE))
 			// Defines all he swizzle operator as functions
-			GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, detail::tvec3, detail::tref2, detail::tref3, x, y, z)
-			GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, detail::tvec3, detail::tvec2, detail::tvec3, detail::tvec4, x, y, z)
+			GLM_SWIZZLE_GEN_REF_FROM_VEC3_COMP(T, P, detail::tvec3, detail::tref2, detail::tref3, x, y, z)
+			GLM_SWIZZLE_GEN_VEC_FROM_VEC3_COMP(T, P, detail::tvec3, detail::tvec2, detail::tvec3, detail::tvec4, x, y, z)
 #		endif//(defined(GLM_SWIZZLE))
 #	endif//GLM_COMPONENT
 
@@ -105,7 +100,7 @@ namespace detail
 		// Implicit basic constructors
 
 		GLM_FUNC_DECL tvec3();
-		GLM_FUNC_DECL tvec3(tvec3<T> const & v);
+		GLM_FUNC_DECL tvec3(tvec3<T, P> const & v);
 
 		//////////////////////////////////////
 		// Explicit basic constructors
@@ -123,137 +118,135 @@ namespace detail
 		// Convertion scalar constructors
 
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
+		template <typename U>
 		GLM_FUNC_DECL explicit tvec3(
 			U const & x);
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U, typename V, typename W> 
+		template <typename U, typename V, typename W>
 		GLM_FUNC_DECL explicit tvec3(
-			U const & x, 
-			V const & y, 
+			U const & x,
+			V const & y,
 			W const & z);			
 
 		//////////////////////////////////////
 		// Convertion vector constructors
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec3(tvec2<A> const & v, B const & s);
+		template <typename A, typename B>
+		GLM_FUNC_DECL explicit tvec3(tvec2<A, P> const & v, B const & s);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec3(A const & s, tvec2<B> const & v);
+		template <typename A, typename B>
+		GLM_FUNC_DECL explicit tvec3(A const & s, tvec2<B, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
-		GLM_FUNC_DECL explicit tvec3(tvec3<U> const & v);
+		template <typename U>
+		GLM_FUNC_DECL explicit tvec3(tvec3<U, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		GLM_FUNC_DECL explicit tvec3(tvec4<U> const & v);
+		GLM_FUNC_DECL explicit tvec3(tvec4<U, P> const & v);
 
 		//////////////////////////////////////
 		// Swizzle constructors
 
-		GLM_FUNC_DECL tvec3(tref3<T> const & r);
+		GLM_FUNC_DECL tvec3(tref3<T, P> const & r);
 
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec3(tref2<A> const & v, B const & s);
+		GLM_FUNC_DECL explicit tvec3(tref2<A, P> const & v, B const & s);
 
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec3(A const & s, tref2<B> const & v);
+		GLM_FUNC_DECL explicit tvec3(A const & s, tref2<B, P> const & v);
 
 		template <int E0, int E1, int E2>
-		GLM_FUNC_DECL tvec3(glm::detail::swizzle<3, T, tvec3<T>, E0, E1, E2, -1> const & that)
+		GLM_FUNC_DECL tvec3(glm::detail::swizzle<3, T, tvec3<T, P>, E0, E1, E2, -1> const & that)
 		{
 			*this = that();
 		}
 
 		template <int E0, int E1>
-		GLM_FUNC_DECL tvec3(glm::detail::swizzle<2, T, tvec2<T>, E0, E1, -1, -2> const & v, T const & s)
+		GLM_FUNC_DECL tvec3(glm::detail::swizzle<2, T, tvec2<T, P>, E0, E1, -1, -2> const & v, T const & s)
 		{
-			*this = tvec3<T>(v(), s);
+			*this = tvec3<T, P>(v(), s);
 		}
 
 		template <int E0, int E1>
-		GLM_FUNC_DECL tvec3(T const & s, glm::detail::swizzle<2, T, tvec2<T>, E0, E1, -1, -2> const & v)
+		GLM_FUNC_DECL tvec3(T const & s, glm::detail::swizzle<2, T, tvec2<T, P>, E0, E1, -1, -2> const & v)
 		{
-			*this = tvec3<T>(s, v());
+			*this = tvec3<T, P>(s, v());
 		}
 
 		//////////////////////////////////////
 		// Unary arithmetic operators
 
-		GLM_FUNC_DECL tvec3<T> & operator= (tvec3<T> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator= (tvec3<T, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec3<T> & operator= (tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator= (tvec3<U, P> const & v);
 
 		template <typename U> 
-		GLM_FUNC_DECL tvec3<T> & operator+=(U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator+=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec3<T> & operator+=(tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator+=(tvec3<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec3<T> & operator-=(U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator-=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec3<T> & operator-=(tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator-=(tvec3<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec3<T> & operator*=(U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator*=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec3<T> & operator*=(tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator*=(tvec3<U, P> const & v);
 		template <typename U> 
-		GLM_FUNC_DECL tvec3<T> & operator/=(U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator/=(U const & s);
 		template <typename U> 
-		GLM_FUNC_DECL tvec3<T> & operator/=(tvec3<U> const & v);
-		GLM_FUNC_DECL tvec3<T> & operator++();
-		GLM_FUNC_DECL tvec3<T> & operator--();
+		GLM_FUNC_DECL tvec3<T, P> & operator/=(tvec3<U, P> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator++();
+		GLM_FUNC_DECL tvec3<T, P> & operator--();
 
 		//////////////////////////////////////
 		// Unary bit operators
 
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator%= (U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator%= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator%= (tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator%= (tvec3<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator&= (U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator&= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator&= (tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator&= (tvec3<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator|= (U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator|= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator|= (tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator|= (tvec3<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator^= (U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator^= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator^= (tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator^= (tvec3<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator<<=(U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator<<=(U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator<<=(tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator<<=(tvec3<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator>>=(U const & s);
+		GLM_FUNC_DECL tvec3<T, P> & operator>>=(U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec3<T> & operator>>=(tvec3<U> const & v);
+		GLM_FUNC_DECL tvec3<T, P> & operator>>=(tvec3<U, P> const & v);
 
 		//////////////////////////////////////
 		// Swizzle operators
 
 		GLM_FUNC_DECL value_type swizzle(comp X) const;
-		GLM_FUNC_DECL tvec2<T> swizzle(comp X, comp Y) const;
-		GLM_FUNC_DECL tvec3<T> swizzle(comp X, comp Y, comp Z) const;
-		GLM_FUNC_DECL tvec4<T> swizzle(comp X, comp Y, comp Z, comp W) const;
-		GLM_FUNC_DECL tref2<T> swizzle(comp X, comp Y);
-		GLM_FUNC_DECL tref3<T> swizzle(comp X, comp Y, comp Z);
+		GLM_FUNC_DECL tvec2<T, P> swizzle(comp X, comp Y) const;
+		GLM_FUNC_DECL tvec3<T, P> swizzle(comp X, comp Y, comp Z) const;
+		GLM_FUNC_DECL tvec4<T, P> swizzle(comp X, comp Y, comp Z, comp W) const;
+		GLM_FUNC_DECL tref2<T, P> swizzle(comp X, comp Y);
+		GLM_FUNC_DECL tref3<T, P> swizzle(comp X, comp Y, comp Z);
 	};
 
-	template <typename T>
+	template <typename T, precision P>
 	struct tref3
 	{
 		GLM_FUNC_DECL tref3(T & x, T & y, T & z);
-		GLM_FUNC_DECL tref3(tref3<T> const & r);
-		GLM_FUNC_DECL explicit tref3(tvec3<T> const & v);
-
-		GLM_FUNC_DECL tref3<T> & operator= (tref3<T> const & r);
-		GLM_FUNC_DECL tref3<T> & operator= (tvec3<T> const & v);
-
-		GLM_FUNC_DECL tvec3<T> operator() ();
+		GLM_FUNC_DECL tref3(tref3<T, P> const & r);
+		GLM_FUNC_DECL explicit tref3(tvec3<T, P> const & v);
+		GLM_FUNC_DECL tref3<T, P> & operator= (tref3<T, P> const & r);
+		GLM_FUNC_DECL tref3<T, P> & operator= (tvec3<T, P> const & v);
+		GLM_FUNC_DECL tvec3<T, P> operator() ();
 
 		T & x;
 		T & y;

文件差异内容过多而无法显示
+ 293 - 301
glm/core/type_vec3.inl


+ 72 - 79
glm/core/type_vec4.hpp

@@ -36,20 +36,15 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> struct tref1;
-	template <typename T> struct tref2;
-	template <typename T> struct tref3;
-	template <typename T> struct tref4;
-
-	template <typename T>
+	template <typename T, precision P>
 	struct tvec4
 	{
 		enum ctor{null};
 
 		typedef T value_type;
 		typedef std::size_t size_type;
-		typedef tvec4<T> type;
-		typedef tvec4<bool> bool_type;
+		typedef tvec4<T, P> type;
+		typedef tvec4<bool, P> bool_type;
 
 		GLM_FUNC_DECL GLM_CONSTEXPR size_type length() const;
 
@@ -83,16 +78,16 @@ namespace detail
 
 #		if(defined(GLM_SWIZZLE))
 			// Defines all he swizzle operator as functions
-			GLM_SWIZZLE_GEN_REF_FROM_VEC4(T, detail::tvec4, detail::tref2, detail::tref3, detail::tref4)
-			GLM_SWIZZLE_GEN_VEC_FROM_VEC4(T, detail::tvec4, detail::tvec2, detail::tvec3, detail::tvec4)
+			GLM_SWIZZLE_GEN_REF_FROM_VEC4(T, P, detail::tvec4, detail::tref2, detail::tref3, detail::tref4)
+			GLM_SWIZZLE_GEN_VEC_FROM_VEC4(T, P, detail::tvec4, detail::tvec2, detail::tvec3, detail::tvec4)
 #		endif//(defined(GLM_SWIZZLE))
 #	else //(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW)
 		value_type x, y, z, w;
 
 #		if(defined(GLM_SWIZZLE))
 			// Defines all he swizzle operator as functions
-			GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, detail::tvec4, detail::tref2, detail::tref3, detail::tref4, x, y, z, w)
-			GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, detail::tvec4, detail::tvec2, detail::tvec3, detail::tvec4, x, y, z, w)
+			GLM_SWIZZLE_GEN_REF_FROM_VEC4_COMP(T, P, detail::tvec4, detail::tref2, detail::tref3, detail::tref4, x, y, z, w)
+			GLM_SWIZZLE_GEN_VEC_FROM_VEC4_COMP(T, P, detail::tvec4, detail::tvec2, detail::tvec3, detail::tvec4, x, y, z, w)
 #		endif//(defined(GLM_SWIZZLE))
 #	endif//GLM_COMPONENT
 
@@ -141,175 +136,173 @@ namespace detail
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B, typename C> 
-		GLM_FUNC_DECL explicit tvec4(tvec2<A> const & v, B const & s1, C const & s2);
+		GLM_FUNC_DECL explicit tvec4(tvec2<A, P> const & v, B const & s1, C const & s2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B, typename C> 
-		GLM_FUNC_DECL explicit tvec4(A const & s1, tvec2<B> const & v, C const & s2);
+		GLM_FUNC_DECL explicit tvec4(A const & s1, tvec2<B, P> const & v, C const & s2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B, typename C> 
-		GLM_FUNC_DECL explicit tvec4(A const & s1, B const & s2, tvec2<C> const & v);
+		GLM_FUNC_DECL explicit tvec4(A const & s1, B const & s2, tvec2<C, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec4(tvec3<A> const & v, B const & s);
+		GLM_FUNC_DECL explicit tvec4(tvec3<A, P> const & v, B const & s);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec4(A const & s, tvec3<B> const & v);
+		GLM_FUNC_DECL explicit tvec4(A const & s, tvec3<B, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec4(tvec2<A> const & v1, tvec2<B> const & v2);
+		GLM_FUNC_DECL explicit tvec4(tvec2<A, P> const & v1, tvec2<B, P> const & v2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		GLM_FUNC_DECL explicit tvec4(tvec4<U> const & v);
+		GLM_FUNC_DECL explicit tvec4(tvec4<U, P> const & v);
 
 		template <int E0, int E1, int E2, int E3>
-		GLM_FUNC_DECL tvec4(glm::detail::swizzle<4, T, tvec4<T>, E0, E1, E2, E3> const & that)
+		GLM_FUNC_DECL tvec4(glm::detail::swizzle<4, T, tvec4<T, P>, E0, E1, E2, E3> const & that)
 		{
 			*this = that();
 		}
 
 		template <int E0, int E1, int F0, int F1>
-		GLM_FUNC_DECL tvec4(glm::detail::swizzle<2, T, tvec2<T>, E0, E1, -1, -2> const & v, glm::detail::swizzle<2, T, tvec2<T>, F0, F1, -1, -2> const & u)
+		GLM_FUNC_DECL tvec4(glm::detail::swizzle<2, T, tvec2<T, P>, E0, E1, -1, -2> const & v, glm::detail::swizzle<2, T, tvec2<T, P>, F0, F1, -1, -2> const & u)
 		{
-			*this = tvec4<T>(v(), u());
+			*this = tvec4<T, P>(v(), u());
 		}
 
 		template <int E0, int E1>
-		GLM_FUNC_DECL tvec4(T const & x, T const & y, glm::detail::swizzle<2, T, tvec2<T>, E0, E1, -1, -2> const & v)
+		GLM_FUNC_DECL tvec4(T const & x, T const & y, glm::detail::swizzle<2, T, tvec2<T, P>, E0, E1, -1, -2> const & v)
 		{
-			*this = tvec4<T>(x, y, v());
+			*this = tvec4<T, P>(x, y, v());
 		}
 
 		template <int E0, int E1>
-		GLM_FUNC_DECL tvec4(T const & x, glm::detail::swizzle<2, T, tvec2<T>, E0, E1, -1, -2> const & v, T const & w)
+		GLM_FUNC_DECL tvec4(T const & x, glm::detail::swizzle<2, T, tvec2<T, P>, E0, E1, -1, -2> const & v, T const & w)
 		{
-			*this = tvec4<T>(x, v(), w);
+			*this = tvec4<T, P>(x, v(), w);
 		}
 
 		template <int E0, int E1>
-		GLM_FUNC_DECL tvec4(glm::detail::swizzle<2, T, tvec2<T>, E0, E1, -1, -2> const & v, T const & z, T const & w)
+		GLM_FUNC_DECL tvec4(glm::detail::swizzle<2, T, tvec2<T, P>, E0, E1, -1, -2> const & v, T const & z, T const & w)
 		{
-			*this = tvec4<T>(v(), z, w);
+			*this = tvec4<T, P>(v(), z, w);
 		}
 
 		template <int E0, int E1, int E2>
-		GLM_FUNC_DECL tvec4(glm::detail::swizzle<3, T, tvec3<T>, E0, E1, E2, -1> const & v, T const & w)
+		GLM_FUNC_DECL tvec4(glm::detail::swizzle<3, T, tvec3<T, P>, E0, E1, E2, -1> const & v, T const & w)
 		{
-			*this = tvec4<T>(v(), w);
+			*this = tvec4<T, P>(v(), w);
 		}
 
 		template <int E0, int E1, int E2>
-		GLM_FUNC_DECL tvec4(T const & x, glm::detail::swizzle<3, T, tvec3<T>, E0, E1, E2, -1> const & v)
+		GLM_FUNC_DECL tvec4(T const & x, glm::detail::swizzle<3, T, tvec3<T, P>, E0, E1, E2, -1> const & v)
 		{
-			*this = tvec4<T>(x, v());
+			*this = tvec4<T, P>(x, v());
 		}
 
 		//////////////////////////////////////
 		// Swizzle constructors
 
-		GLM_FUNC_DECL tvec4(tref4<T> const & r);
+		GLM_FUNC_DECL tvec4(tref4<T, P> const & r);
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B, typename C> 
-		GLM_FUNC_DECL explicit tvec4(tref2<A> const & v, B const & s1, C const & s2);
+		GLM_FUNC_DECL explicit tvec4(tref2<A, P> const & v, B const & s1, C const & s2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B, typename C> 
-		GLM_FUNC_DECL explicit tvec4(A const & s1, tref2<B> const & v, C const & s2);
+		GLM_FUNC_DECL explicit tvec4(A const & s1, tref2<B, P> const & v, C const & s2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B, typename C> 
-		GLM_FUNC_DECL explicit tvec4(A const & s1, B const & s2, tref2<C> const & v);
+		GLM_FUNC_DECL explicit tvec4(A const & s1, B const & s2, tref2<C, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec4(tref3<A> const & v, B const & s);
+		GLM_FUNC_DECL explicit tvec4(tref3<A, P> const & v, B const & s);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec4(A const & s, tref3<B> const & v);
+		GLM_FUNC_DECL explicit tvec4(A const & s, tref3<B, P> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec4(tref2<A> const & v1, tref2<B> const & v2);
+		GLM_FUNC_DECL explicit tvec4(tref2<A, P> const & v1, tref2<B, P> const & v2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec4(tvec2<A> const & v1, tref2<B> const & v2);
+		GLM_FUNC_DECL explicit tvec4(tvec2<A, P> const & v1, tref2<B, P> const & v2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		GLM_FUNC_DECL explicit tvec4(tref2<A> const & v1, tvec2<B> const & v2);
+		GLM_FUNC_DECL explicit tvec4(tref2<A, P> const & v1, tvec2<B, P> const & v2);
 
 		//////////////////////////////////////
 		// Unary arithmetic operators
 
-		GLM_FUNC_DECL tvec4<T> & operator= (tvec4<T> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator= (tvec4<T, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator= (tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator= (tvec4<U, P> const & v);
 
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator+=(U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator+=(U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator+=(tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator+=(tvec4<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator-=(U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator-=(U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator-=(tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator-=(tvec4<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator*=(U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator*=(U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator*=(tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator*=(tvec4<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator/=(U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator/=(U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator/=(tvec4<U> const & v);
-		GLM_FUNC_DECL tvec4<T> & operator++();
-		GLM_FUNC_DECL tvec4<T> & operator--();
+		GLM_FUNC_DECL tvec4<T, P> & operator/=(tvec4<U, P> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator++();
+		GLM_FUNC_DECL tvec4<T, P> & operator--();
 
 		//////////////////////////////////////
 		// Unary bit operators
 
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator%= (U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator%= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator%= (tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator%= (tvec4<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator&= (U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator&= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator&= (tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator&= (tvec4<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator|= (U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator|= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator|= (tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator|= (tvec4<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator^= (U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator^= (U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator^= (tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator^= (tvec4<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator<<=(U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator<<=(U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator<<=(tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator<<=(tvec4<U, P> const & v);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator>>=(U const & s);
+		GLM_FUNC_DECL tvec4<T, P> & operator>>=(U const & s);
 		template <typename U>
-		GLM_FUNC_DECL tvec4<T> & operator>>=(tvec4<U> const & v);
+		GLM_FUNC_DECL tvec4<T, P> & operator>>=(tvec4<U, P> const & v);
 
 		//////////////////////////////////////
 		// Swizzle operators
 
 		GLM_FUNC_DECL value_type swizzle(comp X) const;
-		GLM_FUNC_DECL tvec2<T> swizzle(comp X, comp Y) const;
-		GLM_FUNC_DECL tvec3<T> swizzle(comp X, comp Y, comp Z) const;
-		GLM_FUNC_DECL tvec4<T> swizzle(comp X, comp Y, comp Z, comp W) const;
-		GLM_FUNC_DECL tref2<T> swizzle(comp X, comp Y);
-		GLM_FUNC_DECL tref3<T> swizzle(comp X, comp Y, comp Z);
-		GLM_FUNC_DECL tref4<T> swizzle(comp X, comp Y, comp Z, comp W);
+		GLM_FUNC_DECL tvec2<T, P> swizzle(comp X, comp Y) const;
+		GLM_FUNC_DECL tvec3<T, P> swizzle(comp X, comp Y, comp Z) const;
+		GLM_FUNC_DECL tvec4<T, P> swizzle(comp X, comp Y, comp Z, comp W) const;
+		GLM_FUNC_DECL tref2<T, P> swizzle(comp X, comp Y);
+		GLM_FUNC_DECL tref3<T, P> swizzle(comp X, comp Y, comp Z);
+		GLM_FUNC_DECL tref4<T, P> swizzle(comp X, comp Y, comp Z, comp W);
 	};
 
-	template <typename T>
+	template <typename T, precision P>
 	struct tref4
 	{
 		GLM_FUNC_DECL tref4(T & x, T & y, T & z, T & w);
-		GLM_FUNC_DECL tref4(tref4<T> const & r);
-		GLM_FUNC_DECL explicit tref4(tvec4<T> const & v);
-
-		GLM_FUNC_DECL tref4<T> & operator= (tref4<T> const & r);
-		GLM_FUNC_DECL tref4<T> & operator= (tvec4<T> const & v);
-
-		GLM_FUNC_DECL tvec4<T> operator() ();
+		GLM_FUNC_DECL tref4(tref4<T, P> const & r);
+		GLM_FUNC_DECL explicit tref4(tvec4<T, P> const & v);
+		GLM_FUNC_DECL tref4<T, P> & operator= (tref4<T, P> const & r);
+		GLM_FUNC_DECL tref4<T, P> & operator= (tvec4<T, P> const & v);
+		GLM_FUNC_DECL tvec4<T, P> operator() ();
 
 		T & x;
 		T & y;

文件差异内容过多而无法显示
+ 249 - 251
glm/core/type_vec4.inl


+ 115 - 111
glm/fwd.hpp

@@ -39,44 +39,48 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> struct tquat;
+	template <typename T, precision P> struct tref1;
+	template <typename T, precision P> struct tref2;
+	template <typename T, precision P> struct tref3;
+	template <typename T, precision P> struct tref4;
 	
+	template <typename T, precision P> struct tquat;
 }//namespace detail
 	
 	/// Quaternion of floating-point numbers.
 	///
 	/// @see gtc_quaternion
-	typedef detail::tquat<float>			quat;
+	typedef detail::tquat<float, mediump>			quat;
 	
 	/// Quaternion of half-precision floating-point numbers.
 	///
 	/// @see gtc_quaternion
-	typedef detail::tquat<detail::half>		hquat;
+	typedef detail::tquat<detail::half, mediump>	hquat;
 	
 	/// Quaternion of single-precision floating-point numbers.
 	///
 	/// @see gtc_quaternion
-	typedef detail::tquat<float>			fquat;
+	typedef detail::tquat<float, mediump>			fquat;
 	
 	/// Quaternion of double-precision floating-point numbers.
 	///
 	/// @see gtc_quaternion
-	typedef detail::tquat<double>			dquat;
+	typedef detail::tquat<double, mediump>			dquat;
 	
 	/// Quaternion of low precision floating-point numbers.
 	///
 	/// @see gtc_quaternion
-	typedef detail::tquat<lowp_float>		lowp_quat;
+	typedef detail::tquat<float, lowp>				lowp_quat;
 	
 	/// Quaternion of medium precision floating-point numbers.
 	///
 	/// @see gtc_quaternion
-	typedef detail::tquat<mediump_float>	mediump_quat;
+	typedef detail::tquat<float, mediump>			mediump_quat;
 	
 	/// Quaternion of high precision floating-point numbers.
 	///
 	/// @see gtc_quaternion
-	typedef detail::tquat<highp_float>		highp_quat;
+	typedef detail::tquat<float, highp>				highp_quat;
 
 }//namespace glm
 
@@ -140,70 +144,70 @@ namespace glm
 	
 	/// 8 bit signed integer scalar type.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<i8> i8vec1;
+	typedef detail::tvec1<i8, mediump> i8vec1;
 	
 	/// 8 bit signed integer vector of 2 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<i8> i8vec2;
+	typedef detail::tvec2<i8, mediump> i8vec2;
 	
 	/// 8 bit signed integer vector of 3 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<i8> i8vec3;
+	typedef detail::tvec3<i8, mediump> i8vec3;
 	
 	/// 8 bit signed integer vector of 4 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<i8> i8vec4;
+	typedef detail::tvec4<i8, mediump> i8vec4;
 	
 	
 	/// 16 bit signed integer scalar type.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<i16> i16vec1;
+	typedef detail::tvec1<i16, mediump> i16vec1;
 	
 	/// 16 bit signed integer vector of 2 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<i16> i16vec2;
+	typedef detail::tvec2<i16, mediump> i16vec2;
 	
 	/// 16 bit signed integer vector of 3 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<i16> i16vec3;
+	typedef detail::tvec3<i16, mediump> i16vec3;
 	
 	/// 16 bit signed integer vector of 4 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<i16> i16vec4;
+	typedef detail::tvec4<i16, mediump> i16vec4;
 	
 	
 	/// 32 bit signed integer scalar type.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<i32> i32vec1;
+	typedef detail::tvec1<i32, mediump> i32vec1;
 	
 	/// 32 bit signed integer vector of 2 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<i32> i32vec2;
+	typedef detail::tvec2<i32, mediump> i32vec2;
 	
 	/// 32 bit signed integer vector of 3 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<i32> i32vec3;
+	typedef detail::tvec3<i32, mediump> i32vec3;
 	
 	/// 32 bit signed integer vector of 4 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<i32> i32vec4;
+	typedef detail::tvec4<i32, mediump> i32vec4;
 	
 	
 	/// 64 bit signed integer scalar type.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<i64> i64vec1;
+	typedef detail::tvec1<i64, mediump> i64vec1;
 	
 	/// 64 bit signed integer vector of 2 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<i64> i64vec2;
+	typedef detail::tvec2<i64, mediump> i64vec2;
 	
 	/// 64 bit signed integer vector of 3 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<i64> i64vec3;
+	typedef detail::tvec3<i64, mediump> i64vec3;
 	
 	/// 64 bit signed integer vector of 4 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<i64> i64vec4;
+	typedef detail::tvec4<i64, mediump> i64vec4;
 	
 	
 	/////////////////////////////
@@ -262,70 +266,70 @@ namespace glm
 	
 	/// 8 bit unsigned integer scalar type.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<u8> u8vec1;
+	typedef detail::tvec1<u8, mediump> u8vec1;
 	
 	/// 8 bit unsigned integer vector of 2 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<u8> u8vec2;
+	typedef detail::tvec2<u8, mediump> u8vec2;
 	
 	/// 8 bit unsigned integer vector of 3 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<u8> u8vec3;
+	typedef detail::tvec3<u8, mediump> u8vec3;
 	
 	/// 8 bit unsigned integer vector of 4 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<u8> u8vec4;
+	typedef detail::tvec4<u8, mediump> u8vec4;
 	
 	
 	/// 16 bit unsigned integer scalar type.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<u16> u16vec1;
+	typedef detail::tvec1<u16, mediump> u16vec1;
 	
 	/// 16 bit unsigned integer vector of 2 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<u16> u16vec2;
+	typedef detail::tvec2<u16, mediump> u16vec2;
 	
 	/// 16 bit unsigned integer vector of 3 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<u16> u16vec3;
+	typedef detail::tvec3<u16, mediump> u16vec3;
 	
 	/// 16 bit unsigned integer vector of 4 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<u16> u16vec4;
+	typedef detail::tvec4<u16, mediump> u16vec4;
 	
 	
 	/// 32 bit unsigned integer scalar type.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<u32> u32vec1;
+	typedef detail::tvec1<u32, mediump> u32vec1;
 	
 	/// 32 bit unsigned integer vector of 2 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<u32> u32vec2;
+	typedef detail::tvec2<u32, mediump> u32vec2;
 	
 	/// 32 bit unsigned integer vector of 3 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<u32> u32vec3;
+	typedef detail::tvec3<u32, mediump> u32vec3;
 	
 	/// 32 bit unsigned integer vector of 4 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<u32> u32vec4;
+	typedef detail::tvec4<u32, mediump> u32vec4;
 	
 	
 	/// 64 bit unsigned integer scalar type.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<u64> u64vec1;
+	typedef detail::tvec1<u64, mediump> u64vec1;
 	
 	/// 64 bit unsigned integer vector of 2 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<u64> u64vec2;
+	typedef detail::tvec2<u64, mediump> u64vec2;
 	
 	/// 64 bit unsigned integer vector of 3 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<u64> u64vec3;
+	typedef detail::tvec3<u64, mediump> u64vec3;
 	
 	/// 64 bit unsigned integer vector of 4 components type.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<u64> u64vec4;
+	typedef detail::tvec4<u64, mediump> u64vec4;
 	
 	
 	//////////////////////
@@ -372,70 +376,70 @@ namespace glm
 	
 	/// Single-precision floating-point vector of 1 component.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<float> fvec1;
+	typedef detail::tvec1<float, mediump> fvec1;
 	
 	/// Single-precision floating-point vector of 2 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<float> fvec2;
+	typedef detail::tvec2<float, mediump> fvec2;
 	
 	/// Single-precision floating-point vector of 3 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<float> fvec3;
+	typedef detail::tvec3<float, mediump> fvec3;
 	
 	/// Single-precision floating-point vector of 4 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<float> fvec4;
+	typedef detail::tvec4<float, mediump> fvec4;
 	
 	
 	/// Half-precision floating-point vector of 1 component.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<f16> f16vec1;
+	typedef detail::tvec1<f16, mediump> f16vec1;
 	
 	/// Half-precision floating-point vector of 2 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<f16> f16vec2;
+	typedef detail::tvec2<f16, mediump> f16vec2;
 	
 	/// Half-precision floating-point vector of 3 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<f16> f16vec3;
+	typedef detail::tvec3<f16, mediump> f16vec3;
 	
 	/// Half-precision floating-point vector of 4 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<f16> f16vec4;
+	typedef detail::tvec4<f16, mediump> f16vec4;
 	
 	
 	/// Single-precision floating-point vector of 1 component.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<f32> f32vec1;
+	typedef detail::tvec1<f32, mediump> f32vec1;
 	
 	/// Single-precision floating-point vector of 2 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<f32> f32vec2;
+	typedef detail::tvec2<f32, mediump> f32vec2;
 	
 	/// Single-precision floating-point vector of 3 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<f32> f32vec3;
+	typedef detail::tvec3<f32, mediump> f32vec3;
 	
 	/// Single-precision floating-point vector of 4 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<f32> f32vec4;
+	typedef detail::tvec4<f32, mediump> f32vec4;
 	
 	
 	/// Double-precision floating-point vector of 1 component.
 	/// @see gtc_type_precision
-	typedef detail::tvec1<f64> f64vec1;
+	typedef detail::tvec1<f64, mediump> f64vec1;
 	
 	/// Double-precision floating-point vector of 2 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec2<f64> f64vec2;
+	typedef detail::tvec2<f64, mediump> f64vec2;
 	
 	/// Double-precision floating-point vector of 3 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec3<f64> f64vec3;
+	typedef detail::tvec3<f64, mediump> f64vec3;
 	
 	/// Double-precision floating-point vector of 4 components.
 	/// @see gtc_type_precision
-	typedef detail::tvec4<f64> f64vec4;
+	typedef detail::tvec4<f64, mediump> f64vec4;
 	
 	
 	//////////////////////
@@ -443,19 +447,19 @@ namespace glm
 	
 	/// Single-precision floating-point 1x1 matrix.
 	/// @see gtc_type_precision
-	//typedef detail::tmat1x1<f32> fmat1;
+	//typedef detail::tmat1x1<f32, mediump> fmat1;
 	
 	/// Single-precision floating-point 2x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f32> fmat2;
+	typedef detail::tmat2x2<f32, mediump> fmat2;
 	
 	/// Single-precision floating-point 3x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f32> fmat3;
+	typedef detail::tmat3x3<f32, mediump> fmat3;
 	
 	/// Single-precision floating-point 4x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f32> fmat4;
+	typedef detail::tmat4x4<f32, mediump> fmat4;
 	
 	
 	/// Single-precision floating-point 1x1 matrix.
@@ -464,56 +468,56 @@ namespace glm
 	
 	/// Single-precision floating-point 2x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f32> fmat2x2;
+	typedef detail::tmat2x2<f32, mediump> fmat2x2;
 	
 	/// Single-precision floating-point 2x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x3<f32> fmat2x3;
+	typedef detail::tmat2x3<f32, mediump> fmat2x3;
 	
 	/// Single-precision floating-point 2x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x4<f32> fmat2x4;
+	typedef detail::tmat2x4<f32, mediump> fmat2x4;
 	
 	/// Single-precision floating-point 3x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x2<f32> fmat3x2;
+	typedef detail::tmat3x2<f32, mediump> fmat3x2;
 	
 	/// Single-precision floating-point 3x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f32> fmat3x3;
+	typedef detail::tmat3x3<f32, mediump> fmat3x3;
 	
 	/// Single-precision floating-point 3x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x4<f32> fmat3x4;
+	typedef detail::tmat3x4<f32, mediump> fmat3x4;
 	
 	/// Single-precision floating-point 4x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x2<f32> fmat4x2;
+	typedef detail::tmat4x2<f32, mediump> fmat4x2;
 	
 	/// Single-precision floating-point 4x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x3<f32> fmat4x3;
+	typedef detail::tmat4x3<f32, mediump> fmat4x3;
 	
 	/// Single-precision floating-point 4x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f32> fmat4x4;
+	typedef detail::tmat4x4<f32, mediump> fmat4x4;
 	
 	
 	/// Half-precision floating-point 1x1 matrix.
 	/// @see gtc_type_precision
-	//typedef detail::tmat1x1<f16> f16mat1;
+	//typedef detail::tmat1x1<f16, mediump> f16mat1;
 	
 	/// Half-precision floating-point 2x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f16> f16mat2;
+	typedef detail::tmat2x2<f16, mediump> f16mat2;
 	
 	/// Half-precision floating-point 3x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f16> f16mat3;
+	typedef detail::tmat3x3<f16, mediump> f16mat3;
 	
 	/// Half-precision floating-point 4x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f16> f16mat4;
+	typedef detail::tmat4x4<f16, mediump> f16mat4;
 	
 	
 	/// Half-precision floating-point 1x1 matrix.
@@ -522,56 +526,56 @@ namespace glm
 	
 	/// Half-precision floating-point 2x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f16> f16mat2x2;
+	typedef detail::tmat2x2<f16, mediump> f16mat2x2;
 	
 	/// Half-precision floating-point 2x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x3<f16> f16mat2x3;
+	typedef detail::tmat2x3<f16, mediump> f16mat2x3;
 	
 	/// Half-precision floating-point 2x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x4<f16> f16mat2x4;
+	typedef detail::tmat2x4<f16, mediump> f16mat2x4;
 	
 	/// Half-precision floating-point 3x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x2<f16> f16mat3x2;
+	typedef detail::tmat3x2<f16, mediump> f16mat3x2;
 	
 	/// Half-precision floating-point 3x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f16> f16mat3x3;
+	typedef detail::tmat3x3<f16, mediump> f16mat3x3;
 	
 	/// Half-precision floating-point 3x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x4<f16> f16mat3x4;
+	typedef detail::tmat3x4<f16, mediump> f16mat3x4;
 	
 	/// Half-precision floating-point 4x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x2<f16> f16mat4x2;
+	typedef detail::tmat4x2<f16, mediump> f16mat4x2;
 	
 	/// Half-precision floating-point 4x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x3<f16> f16mat4x3;
+	typedef detail::tmat4x3<f16, mediump> f16mat4x3;
 	
 	/// Half-precision floating-point 4x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f16> f16mat4x4;
+	typedef detail::tmat4x4<f16, mediump> f16mat4x4;
 	
 	
 	/// Single-precision floating-point 1x1 matrix.
 	/// @see gtc_type_precision
-	//typedef detail::tmat1x1<f32> f32mat1;
+	//typedef detail::tmat1x1<f32, mediump> f32mat1;
 	
 	/// Single-precision floating-point 2x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f32> f32mat2;
+	typedef detail::tmat2x2<f32, mediump> f32mat2;
 	
 	/// Single-precision floating-point 3x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f32> f32mat3;
+	typedef detail::tmat3x3<f32, mediump> f32mat3;
 	
 	/// Single-precision floating-point 4x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f32> f32mat4;
+	typedef detail::tmat4x4<f32, mediump> f32mat4;
 	
 	
 	/// Single-precision floating-point 1x1 matrix.
@@ -580,56 +584,56 @@ namespace glm
 	
 	/// Single-precision floating-point 2x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f32> f32mat2x2;
+	typedef detail::tmat2x2<f32, mediump> f32mat2x2;
 	
 	/// Single-precision floating-point 2x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x3<f32> f32mat2x3;
+	typedef detail::tmat2x3<f32, mediump> f32mat2x3;
 	
 	/// Single-precision floating-point 2x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x4<f32> f32mat2x4;
+	typedef detail::tmat2x4<f32, mediump> f32mat2x4;
 	
 	/// Single-precision floating-point 3x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x2<f32> f32mat3x2;
+	typedef detail::tmat3x2<f32, mediump> f32mat3x2;
 	
 	/// Single-precision floating-point 3x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f32> f32mat3x3;
+	typedef detail::tmat3x3<f32, mediump> f32mat3x3;
 	
 	/// Single-precision floating-point 3x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x4<f32> f32mat3x4;
+	typedef detail::tmat3x4<f32, mediump> f32mat3x4;
 	
 	/// Single-precision floating-point 4x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x2<f32> f32mat4x2;
+	typedef detail::tmat4x2<f32, mediump> f32mat4x2;
 	
 	/// Single-precision floating-point 4x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x3<f32> f32mat4x3;
+	typedef detail::tmat4x3<f32, mediump> f32mat4x3;
 	
 	/// Single-precision floating-point 4x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f32> f32mat4x4;
+	typedef detail::tmat4x4<f32, mediump> f32mat4x4;
 	
 	
 	/// Double-precision floating-point 1x1 matrix.
 	/// @see gtc_type_precision
-	//typedef detail::tmat1x1<f64> f64mat1;
+	//typedef detail::tmat1x1<f64, mediump> f64mat1;
 	
 	/// Double-precision floating-point 2x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f64> f64mat2;
+	typedef detail::tmat2x2<f64, mediump> f64mat2;
 	
 	/// Double-precision floating-point 3x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f64> f64mat3;
+	typedef detail::tmat3x3<f64, mediump> f64mat3;
 	
 	/// Double-precision floating-point 4x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f64> f64mat4;
+	typedef detail::tmat4x4<f64, mediump> f64mat4;
 	
 	
 	/// Double-precision floating-point 1x1 matrix.
@@ -638,39 +642,39 @@ namespace glm
 	
 	/// Double-precision floating-point 2x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f64> f64mat2x2;
+	typedef detail::tmat2x2<f64, mediump> f64mat2x2;
 	
 	/// Double-precision floating-point 2x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x3<f64> f64mat2x3;
+	typedef detail::tmat2x3<f64, mediump> f64mat2x3;
 	
 	/// Double-precision floating-point 2x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat2x4<f64> f64mat2x4;
+	typedef detail::tmat2x4<f64, mediump> f64mat2x4;
 	
 	/// Double-precision floating-point 3x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x2<f64> f64mat3x2;
+	typedef detail::tmat3x2<f64, mediump> f64mat3x2;
 	
 	/// Double-precision floating-point 3x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f64> f64mat3x3;
+	typedef detail::tmat3x3<f64, mediump> f64mat3x3;
 	
 	/// Double-precision floating-point 3x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat3x4<f64> f64mat3x4;
+	typedef detail::tmat3x4<f64, mediump> f64mat3x4;
 	
 	/// Double-precision floating-point 4x2 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x2<f64> f64mat4x2;
+	typedef detail::tmat4x2<f64, mediump> f64mat4x2;
 	
 	/// Double-precision floating-point 4x3 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x3<f64> f64mat4x3;
+	typedef detail::tmat4x3<f64, mediump> f64mat4x3;
 	
 	/// Double-precision floating-point 4x4 matrix.
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f64> f64mat4x4;
+	typedef detail::tmat4x4<f64, mediump> f64mat4x4;
 	
 	
 	//////////////////////////
@@ -678,15 +682,15 @@ namespace glm
 	
 	/// Half-precision floating-point quaternion.
 	/// @see gtc_type_precision
-	typedef detail::tquat<f16> f16quat;
+	typedef detail::tquat<f16, mediump> f16quat;
 	
 	/// Single-precision floating-point quaternion.
 	/// @see gtc_type_precision
-	typedef detail::tquat<f32> f32quat;
+	typedef detail::tquat<f32, mediump> f32quat;
 	
 	/// Double-precision floating-point quaternion. 
 	/// @see gtc_type_precision
-	typedef detail::tquat<f64> f64quat;
+	typedef detail::tquat<f64, mediump> f64quat;
 }//namespace glm
 
 #endif//GLM_FWD_INCLUDED

+ 1 - 0
glm/glm.hpp

@@ -84,6 +84,7 @@
 #include <climits>
 #include <cfloat>
 #include <limits>
+#include <cassert>
 //#include <cstdint>
 //#include <type_traits>
 

+ 84 - 84
glm/gtc/epsilon.inl

@@ -88,196 +88,196 @@ namespace glm
 		return abs(x - y) >= epsilon;
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<bool> epsilonEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool, P> epsilonEqual
 	(
-		detail::tvec2<valType> const & x,
-		detail::tvec2<valType> const & y,
-		valType const & epsilon)
+		detail::tvec2<T, P> const & x,
+		detail::tvec2<T, P> const & y,
+		T const & epsilon)
 	{
-		return detail::tvec2<bool>(
+		return detail::tvec2<bool, P>(
 			abs(x.x - y.x) < epsilon,
 			abs(x.y - y.y) < epsilon);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<bool> epsilonEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool, P> epsilonEqual
 	(
-		detail::tvec2<valType> const & x,
-		detail::tvec2<valType> const & y,
-		detail::tvec2<valType> const & epsilon
+		detail::tvec2<T, P> const & x,
+		detail::tvec2<T, P> const & y,
+		detail::tvec2<T, P> const & epsilon
 	)
 	{
-		return detail::tvec2<bool>(
+		return detail::tvec2<bool, P>(
 			abs(x.x - y.x) < epsilon.x,
 			abs(x.y - y.y) < epsilon.y);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<bool> epsilonEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool, P> epsilonEqual
 	(
-		detail::tvec3<valType> const & x,
-		detail::tvec3<valType> const & y,
-		valType const & epsilon)
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
+		T const & epsilon)
 	{
-		return detail::tvec3<bool>(
+		return detail::tvec3<bool, P>(
 			abs(x.x - y.x) < epsilon,
 			abs(x.y - y.y) < epsilon,
 			abs(x.z - y.z) < epsilon);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<bool> epsilonEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool, P> epsilonEqual
 	(
-		detail::tvec3<valType> const & x,
-		detail::tvec3<valType> const & y,
-		detail::tvec3<valType> const & epsilon
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
+		detail::tvec3<T, P> const & epsilon
 	)
 	{
-		return detail::tvec3<bool>(
+		return detail::tvec3<bool, P>(
 			abs(x.x - y.x) < epsilon.x,
 			abs(x.y - y.y) < epsilon.y,
 			abs(x.z - y.z) < epsilon.z);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<bool> epsilonEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> epsilonEqual
 	(
-		detail::tvec4<valType> const & x,
-		detail::tvec4<valType> const & y,
-		valType const & epsilon
+		detail::tvec4<T, P> const & x,
+		detail::tvec4<T, P> const & y,
+		T const & epsilon
 	)
 	{
-		return detail::tvec4<bool>(
+		return detail::tvec4<bool, P>(
 			abs(x.x - y.x) < epsilon,
 			abs(x.y - y.y) < epsilon,
 			abs(x.z - y.z) < epsilon,
 			abs(x.w - y.w) < epsilon);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<bool> epsilonEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> epsilonEqual
 	(
-		detail::tvec4<valType> const & x,
-		detail::tvec4<valType> const & y,
-		detail::tvec4<valType> const & epsilon
+		detail::tvec4<T, P> const & x,
+		detail::tvec4<T, P> const & y,
+		detail::tvec4<T, P> const & epsilon
 	)
 	{
-		return detail::tvec4<bool>(
+		return detail::tvec4<bool, P>(
 			abs(x.x - y.x) < epsilon.x,
 			abs(x.y - y.y) < epsilon.y,
 			abs(x.z - y.z) < epsilon.z,
 			abs(x.w - y.w) < epsilon.w);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<bool> epsilonNotEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool, P> epsilonNotEqual
 	(
-		detail::tvec2<valType> const & x,
-		detail::tvec2<valType> const & y,
-		valType const & epsilon
+		detail::tvec2<T, P> const & x,
+		detail::tvec2<T, P> const & y,
+		T const & epsilon
 	)
 	{
-		return detail::tvec2<bool>(
+		return detail::tvec2<bool, P>(
 			abs(x.x - y.x) >= epsilon,
 			abs(x.y - y.y) >= epsilon);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<bool> epsilonNotEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool, P> epsilonNotEqual
 	(
-		detail::tvec2<valType> const & x,
-		detail::tvec2<valType> const & y,
-		detail::tvec2<valType> const & epsilon
+		detail::tvec2<T, P> const & x,
+		detail::tvec2<T, P> const & y,
+		detail::tvec2<T, P> const & epsilon
 	)
 	{
-		return detail::tvec2<bool>(
+		return detail::tvec2<bool, P>(
 			abs(x.x - y.x) >= epsilon.x,
 			abs(x.y - y.y) >= epsilon.y);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<bool> epsilonNotEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool, P> epsilonNotEqual
 	(
-		detail::tvec3<valType> const & x,
-		detail::tvec3<valType> const & y,
-		valType const & epsilon
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
+		T const & epsilon
 	)
 	{
-		return detail::tvec3<bool>(
+		return detail::tvec3<bool, P>(
 			abs(x.x - y.x) >= epsilon,
 			abs(x.y - y.y) >= epsilon,
 			abs(x.z - y.z) >= epsilon);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<bool> epsilonNotEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool, P> epsilonNotEqual
 	(
-		detail::tvec3<valType> const & x,
-		detail::tvec3<valType> const & y,
-		detail::tvec3<valType> const & epsilon
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
+		detail::tvec3<T, P> const & epsilon
 	)
 	{
-		return detail::tvec3<bool>(
+		return detail::tvec3<bool, P>(
 			abs(x.x - y.x) >= epsilon.x,
 			abs(x.y - y.y) >= epsilon.y,
 			abs(x.z - y.z) >= epsilon.z);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<bool> epsilonNotEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> epsilonNotEqual
 	(
-		detail::tvec4<valType> const & x,
-		detail::tvec4<valType> const & y,
-		valType const & epsilon
+		detail::tvec4<T, P> const & x,
+		detail::tvec4<T, P> const & y,
+		T const & epsilon
 	)
 	{
-		return detail::tvec4<bool>(
+		return detail::tvec4<bool, P>(
 			abs(x.x - y.x) >= epsilon,
 			abs(x.y - y.y) >= epsilon,
 			abs(x.z - y.z) >= epsilon,
 			abs(x.w - y.w) >= epsilon);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<bool> epsilonNotEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> epsilonNotEqual
 	(
-		detail::tvec4<valType> const & x,
-		detail::tvec4<valType> const & y,
-		detail::tvec4<valType> const & epsilon
+		detail::tvec4<T, P> const & x,
+		detail::tvec4<T, P> const & y,
+		detail::tvec4<T, P> const & epsilon
 	)
 	{
-		return detail::tvec4<bool>(
+		return detail::tvec4<bool, P>(
 			abs(x.x - y.x) >= epsilon.x,
 			abs(x.y - y.y) >= epsilon.y,
 			abs(x.z - y.z) >= epsilon.z,
 			abs(x.w - y.w) >= epsilon.w);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<bool> epsilonEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> epsilonEqual
 	(
-		detail::tquat<valType> const & x,
-		detail::tquat<valType> const & y,
-		valType const & epsilon
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y,
+		T const & epsilon
 	)
 	{
-		return detail::tvec4<bool>(
+		return detail::tvec4<bool, P>(
 			abs(x.x - y.x) < epsilon,
 			abs(x.y - y.y) < epsilon,
 			abs(x.z - y.z) < epsilon,
 			abs(x.w - y.w) < epsilon);
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<bool> epsilonNotEqual
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> epsilonNotEqual
 	(
-		detail::tquat<valType> const & x,
-		detail::tquat<valType> const & y,
-		valType const & epsilon
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y,
+		T const & epsilon
 	)
 	{
-		return detail::tvec4<bool>(
+		return detail::tvec4<bool, P>(
 			abs(x.x - y.x) >= epsilon,
 			abs(x.y - y.y) >= epsilon,
 			abs(x.z - y.z) >= epsilon,

+ 381 - 131
glm/gtc/half_float.hpp

@@ -49,7 +49,7 @@ namespace detail
 {
 #if(GLM_COMPONENT == GLM_COMPONENT_CXX98)
 	template <>
-	struct tvec2<half>
+	struct tvec2<half, defaultp>
 	{
 		enum ctor{null};
 		typedef half value_type;
@@ -58,8 +58,8 @@ namespace detail
 		GLM_FUNC_DECL size_type length() const;
 		static GLM_FUNC_DECL size_type value_size();
 
-		typedef tvec2<half> type;
-		typedef tvec2<bool> bool_type;
+		typedef tvec2<half, defaultp> type;
+		typedef tvec2<bool, defaultp> bool_type;
 
 		//////////////////////////////////////
 		// Data
@@ -76,7 +76,7 @@ namespace detail
 		// Implicit basic constructors
 
 		tvec2();
-		tvec2(tvec2<half> const & v);
+		tvec2(tvec2<half, defaultp> const & v);
 
 		//////////////////////////////////////
 		// Explicit basic constructors
@@ -85,22 +85,22 @@ namespace detail
 		explicit tvec2(
 			half const & s);
 		explicit tvec2(
-			half const & s1, 
+			half const & s1,
 			half const & s2);
 
 		//////////////////////////////////////
 		// Swizzle constructors
 
-		tvec2(tref2<half> const & r);
+		tvec2(tref2<half, defaultp> const & r);
 
 		//////////////////////////////////////
 		// Convertion scalar constructors
 
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U> 
+		template <typename U>
 		explicit tvec2(U const & x);
 		//! Explicit converions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
-		template <typename U, typename V> 
+		template <typename U, typename V>
 		explicit tvec2(U const & x, V const & y);			
 
 		//////////////////////////////////////
@@ -108,42 +108,42 @@ namespace detail
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		explicit tvec2(tvec2<U> const & v);
+		explicit tvec2(tvec2<U, defaultp> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		explicit tvec2(tvec3<U> const & v);
+		explicit tvec2(tvec3<U, defaultp> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		explicit tvec2(tvec4<U> const & v);
+		explicit tvec2(tvec4<U, defaultp> const & v);
 
 		//////////////////////////////////////
 		// Unary arithmetic operators
 
-		tvec2<half>& operator= (tvec2<half> const & v);
+		tvec2<half, defaultp>& operator= (tvec2<half, defaultp> const & v);
 
-		tvec2<half>& operator+=(half const & s);
-		tvec2<half>& operator+=(tvec2<half> const & v);
-		tvec2<half>& operator-=(half const & s);
-		tvec2<half>& operator-=(tvec2<half> const & v);
-		tvec2<half>& operator*=(half const & s);
-		tvec2<half>& operator*=(tvec2<half> const & v);
-		tvec2<half>& operator/=(half const & s);
-		tvec2<half>& operator/=(tvec2<half> const & v);
-		tvec2<half>& operator++();
-		tvec2<half>& operator--();
+		tvec2<half, defaultp>& operator+=(half const & s);
+		tvec2<half, defaultp>& operator+=(tvec2<half, defaultp> const & v);
+		tvec2<half, defaultp>& operator-=(half const & s);
+		tvec2<half, defaultp>& operator-=(tvec2<half, defaultp> const & v);
+		tvec2<half, defaultp>& operator*=(half const & s);
+		tvec2<half, defaultp>& operator*=(tvec2<half, defaultp> const & v);
+		tvec2<half, defaultp>& operator/=(half const & s);
+		tvec2<half, defaultp>& operator/=(tvec2<half, defaultp> const & v);
+		tvec2<half, defaultp>& operator++();
+		tvec2<half, defaultp>& operator--();
 
 		//////////////////////////////////////
 		// Swizzle operators
 
 		half swizzle(comp X) const;
-		tvec2<half> swizzle(comp X, comp Y) const;
-		tvec3<half> swizzle(comp X, comp Y, comp Z) const;
-		tvec4<half> swizzle(comp X, comp Y, comp Z, comp W) const;
-		tref2<half> swizzle(comp X, comp Y);
+		tvec2<half, defaultp> swizzle(comp X, comp Y) const;
+		tvec3<half, defaultp> swizzle(comp X, comp Y, comp Z) const;
+		tvec4<half, defaultp> swizzle(comp X, comp Y, comp Z, comp W) const;
+		tref2<half, defaultp> swizzle(comp X, comp Y);
 	};
 
 	template <>
-	struct tvec3<half>
+	struct tvec3<half, defaultp>
 	{
 		enum ctor{null};
 		typedef half value_type;
@@ -151,8 +151,8 @@ namespace detail
 		GLM_FUNC_DECL size_type length() const;
 		static GLM_FUNC_DECL size_type value_size();
 
-		typedef tvec3<half> type;
-		typedef tvec3<bool> bool_type;
+		typedef tvec3<half, defaultp> type;
+		typedef tvec3<bool, defaultp> bool_type;
 
 		//////////////////////////////////////
 		// Data
@@ -169,7 +169,7 @@ namespace detail
 		// Implicit basic constructors
 
 		tvec3();
-		tvec3(tvec3<half> const & v);
+		tvec3(tvec3<half, defaultp> const & v);
 
 		//////////////////////////////////////
 		// Explicit basic constructors
@@ -178,14 +178,14 @@ namespace detail
 		explicit tvec3(
 			half const & s);
 		explicit tvec3(
-			half const & s1, 
-			half const & s2, 
+			half const & s1,
+			half const & s2,
 			half const & s3);
 
 		//////////////////////////////////////
 		// Swizzle constructors
 
-		tvec3(tref3<half> const & r);
+		tvec3(tref3<half, defaultp> const & r);
 
 		//////////////////////////////////////
 		// Convertion scalar constructors
@@ -202,45 +202,45 @@ namespace detail
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		explicit tvec3(tvec2<A> const & v, B const & s);
+		explicit tvec3(tvec2<A, defaultp> const & v, B const & s);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		explicit tvec3(A const & s, tvec2<B> const & v);
+		explicit tvec3(A const & s, tvec2<B, defaultp> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		explicit tvec3(tvec3<U> const & v);
+		explicit tvec3(tvec3<U, defaultp> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		explicit tvec3(tvec4<U> const & v);
+		explicit tvec3(tvec4<U, defaultp> const & v);
 
 		//////////////////////////////////////
 		// Unary arithmetic operators
 
-		tvec3<half>& operator= (tvec3<half> const & v);
+		tvec3<half, defaultp>& operator= (tvec3<half, defaultp> const & v);
 
-		tvec3<half>& operator+=(half const & s);
-		tvec3<half>& operator+=(tvec3<half> const & v);
-		tvec3<half>& operator-=(half const & s);
-		tvec3<half>& operator-=(tvec3<half> const & v);
-		tvec3<half>& operator*=(half const & s);
-		tvec3<half>& operator*=(tvec3<half> const & v);
-		tvec3<half>& operator/=(half const & s);
-		tvec3<half>& operator/=(tvec3<half> const & v);
-		tvec3<half>& operator++();
-		tvec3<half>& operator--();
+		tvec3<half, defaultp>& operator+=(half const & s);
+		tvec3<half, defaultp>& operator+=(tvec3<half, defaultp> const & v);
+		tvec3<half, defaultp>& operator-=(half const & s);
+		tvec3<half, defaultp>& operator-=(tvec3<half, defaultp> const & v);
+		tvec3<half, defaultp>& operator*=(half const & s);
+		tvec3<half, defaultp>& operator*=(tvec3<half, defaultp> const & v);
+		tvec3<half, defaultp>& operator/=(half const & s);
+		tvec3<half, defaultp>& operator/=(tvec3<half, defaultp> const & v);
+		tvec3<half, defaultp>& operator++();
+		tvec3<half, defaultp>& operator--();
 
 		//////////////////////////////////////
 		// Swizzle operators
 
 		half swizzle(comp X) const;
-		tvec2<half> swizzle(comp X, comp Y) const;
-		tvec3<half> swizzle(comp X, comp Y, comp Z) const;
-		tvec4<half> swizzle(comp X, comp Y, comp Z, comp W) const;
-		tref3<half> swizzle(comp X, comp Y, comp Z);
+		tvec2<half, defaultp> swizzle(comp X, comp Y) const;
+		tvec3<half, defaultp> swizzle(comp X, comp Y, comp Z) const;
+		tvec4<half, defaultp> swizzle(comp X, comp Y, comp Z, comp W) const;
+		tref3<half, defaultp> swizzle(comp X, comp Y, comp Z);
 	};
 
 	template <>
-	struct tvec4<half>
+	struct tvec4<half, defaultp>
 	{
 		enum ctor{null};
 		typedef half value_type;
@@ -248,8 +248,8 @@ namespace detail
 		GLM_FUNC_DECL size_type length() const;
 		static GLM_FUNC_DECL size_type value_size();
 
-		typedef tvec4<half> type;
-		typedef tvec4<bool> bool_type;
+		typedef tvec4<half, defaultp> type;
+		typedef tvec4<bool, defaultp> bool_type;
 
 		//////////////////////////////////////
 		// Data
@@ -266,7 +266,7 @@ namespace detail
 		// Implicit basic constructors
 
 		tvec4();
-		tvec4(tvec4<half> const & v);
+		tvec4(tvec4<half, defaultp> const & v);
 
 		//////////////////////////////////////
 		// Explicit basic constructors
@@ -275,15 +275,15 @@ namespace detail
 		explicit tvec4(
 			half const & s);
 		explicit tvec4(
-			half const & s0, 
-			half const & s1, 
-			half const & s2, 
+			half const & s0,
+			half const & s1,
+			half const & s2,
 			half const & s3);
 
 		//////////////////////////////////////
 		// Swizzle constructors
 
-		tvec4(tref4<half> const & r);
+		tvec4(tref4<half, defaultp> const & r);
 
 		//////////////////////////////////////
 		// Convertion scalar constructors
@@ -300,50 +300,50 @@ namespace detail
 
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B, typename C> 
-		explicit tvec4(tvec2<A> const & v, B const & s1, C const & s2);
+		explicit tvec4(tvec2<A, defaultp> const & v, B const & s1, C const & s2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B, typename C> 
-		explicit tvec4(A const & s1, tvec2<B> const & v, C const & s2);
+		explicit tvec4(A const & s1, tvec2<B, defaultp> const & v, C const & s2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B, typename C> 
-		explicit tvec4(A const & s1, B const & s2, tvec2<C> const & v);
+		explicit tvec4(A const & s1, B const & s2, tvec2<C, defaultp> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		explicit tvec4(tvec3<A> const & v, B const & s);
+		explicit tvec4(tvec3<A, defaultp> const & v, B const & s);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		explicit tvec4(A const & s, tvec3<B> const & v);
+		explicit tvec4(A const & s, tvec3<B, defaultp> const & v);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename A, typename B> 
-		explicit tvec4(tvec2<A> const & v1, tvec2<B> const & v2);
+		explicit tvec4(tvec2<A, defaultp> const & v1, tvec2<B, defaultp> const & v2);
 		//! Explicit conversions (From section 5.4.1 Conversion and scalar constructors of GLSL 1.30.08 specification)
 		template <typename U> 
-		explicit tvec4(tvec4<U> const & v);
+		explicit tvec4(tvec4<U, defaultp> const & v);
 
 		//////////////////////////////////////
 		// Unary arithmetic operators
 
-		tvec4<half>& operator= (tvec4<half> const & v);
+		tvec4<half, defaultp>& operator= (tvec4<half, defaultp> const & v);
 
-		tvec4<half>& operator+=(half const & s);
-		tvec4<half>& operator+=(tvec4<half> const & v);
-		tvec4<half>& operator-=(half const & s);
-		tvec4<half>& operator-=(tvec4<half> const & v);
-		tvec4<half>& operator*=(half const & s);
-		tvec4<half>& operator*=(tvec4<half> const & v);
-		tvec4<half>& operator/=(half const & s);
-		tvec4<half>& operator/=(tvec4<half> const & v);
-		tvec4<half>& operator++();
-		tvec4<half>& operator--();
+		tvec4<half, defaultp>& operator+=(half const & s);
+		tvec4<half, defaultp>& operator+=(tvec4<half, defaultp> const & v);
+		tvec4<half, defaultp>& operator-=(half const & s);
+		tvec4<half, defaultp>& operator-=(tvec4<half, defaultp> const & v);
+		tvec4<half, defaultp>& operator*=(half const & s);
+		tvec4<half, defaultp>& operator*=(tvec4<half, defaultp> const & v);
+		tvec4<half, defaultp>& operator/=(half const & s);
+		tvec4<half, defaultp>& operator/=(tvec4<half, defaultp> const & v);
+		tvec4<half, defaultp>& operator++();
+		tvec4<half, defaultp>& operator--();
 
 		//////////////////////////////////////
 		// Swizzle operators
 
 		half swizzle(comp X) const;
-		tvec2<half> swizzle(comp X, comp Y) const;
-		tvec3<half> swizzle(comp X, comp Y, comp Z) const;
-		tvec4<half> swizzle(comp X, comp Y, comp Z, comp W) const;
-		tref4<half> swizzle(comp X, comp Y, comp Z, comp W);
+		tvec2<half, defaultp> swizzle(comp X, comp Y) const;
+		tvec3<half, defaultp> swizzle(comp X, comp Y, comp Z) const;
+		tvec4<half, defaultp> swizzle(comp X, comp Y, comp Z, comp W) const;
+		tref4<half, defaultp> swizzle(comp X, comp Y, comp Z, comp W);
 	};
 #endif//(GLM_COMPONENT == GLM_COMPONENT_CXX98)
 }
@@ -351,71 +351,321 @@ namespace detail
 
 	/// @addtogroup gtc_half_float
 	/// @{
-
-	/// Type for half-precision floating-point numbers. 
+	
+	//////////////////////////////////////////////
+	// High half precision floating-point numbers.
+	
+	/// Vector of 2 high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::half					half;
-
-	/// Vector of 2 half-precision floating-point numbers. 
+	typedef detail::tvec2<half_t, highp>		highp_hvec2;
+	
+	/// Vector of 3 high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tvec2<detail::half>	hvec2;
-
-	/// Vector of 3 half-precision floating-point numbers.
+	typedef detail::tvec3<half_t, highp>		highp_hvec3;
+	
+	/// Vector of 4 high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tvec3<detail::half>	hvec3;
-
-	/// Vector of 4 half-precision floating-point numbers. 
+	typedef detail::tvec4<half_t, highp>		highp_hvec4;
+	
+	/// 2 * 2 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tvec4<detail::half>	hvec4;
-
-	/// 2 * 2 matrix of half-precision floating-point numbers.
+	typedef detail::tmat2x2<half_t, highp>		highp_hmat2;
+	
+	/// 3 * 3 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat2x2<detail::half>	hmat2;
-
-	/// 3 * 3 matrix of half-precision floating-point numbers.
+	typedef detail::tmat3x3<half_t, highp>		highp_hmat3;
+	
+	/// 4 * 4 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat3x3<detail::half>	hmat3;
-
-	/// 4 * 4 matrix of half-precision floating-point numbers.
+	typedef detail::tmat4x4<half_t, highp>		highp_hmat4;
+	
+	/// 2 * 2 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat4x4<detail::half>	hmat4;
-
-	/// 2 * 2 matrix of half-precision floating-point numbers.
+	typedef detail::tmat2x2<half_t, highp>		highp_hmat2x2;
+	
+	/// 2 * 3 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat2x2<detail::half>	hmat2x2;
-
-	/// 2 * 3 matrix of half-precision floating-point numbers.
+	typedef detail::tmat2x3<half_t, highp>		highp_hmat2x3;
+	
+	/// 2 * 4 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat2x3<detail::half>	hmat2x3;
-
-	/// 2 * 4 matrix of half-precision floating-point numbers.
+	typedef detail::tmat2x4<half_t, highp>		highp_hmat2x4;
+	
+	/// 3 * 2 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat2x4<detail::half>	hmat2x4;
-
-	/// 3 * 2 matrix of half-precision floating-point numbers.
+	typedef detail::tmat3x2<half_t, highp>		highp_hmat3x2;
+	
+	/// 3 * 3 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat3x2<detail::half>	hmat3x2;
-
-	/// 3 * 3 matrix of half-precision floating-point numbers.
+	typedef detail::tmat3x3<half_t, highp>		highp_hmat3x3;
+	
+	/// 3 * 4 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat3x3<detail::half>	hmat3x3;
-
-	/// 3 * 4 matrix of half-precision floating-point numbers.
+	typedef detail::tmat3x4<half_t, highp>		highp_hmat3x4;
+	
+	/// 4 * 2 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat3x4<detail::half>	hmat3x4;
-
-	/// 4 * 2 matrix of half-precision floating-point numbers.
+	typedef detail::tmat4x2<half_t, highp>		highp_hmat4x2;
+	
+	/// 4 * 3 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat4x2<detail::half>	hmat4x2;    
-
-	/// 4 * 3 matrix of half-precision floating-point numbers.
+	typedef detail::tmat4x3<half_t, highp>		highp_hmat4x3;
+	
+	/// 4 * 4 matrix of high half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat4x3<detail::half>	hmat4x3;
-
-	/// 4 * 4 matrix of half-precision floating-point numbers.
+	typedef detail::tmat4x4<half_t, highp>		highp_hmat4x4;
+	
+	//////////////////////////////////////////////
+	// Medium half precision floating-point numbers.
+	
+	/// Vector of 2 medium half-precision floating-point numbers.
 	/// @see gtc_half_float
-	typedef detail::tmat4x4<detail::half>	hmat4x4;
-
+	typedef detail::tvec2<half_t, mediump>		mediump_hvec2;
+	
+	/// Vector of 3 medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tvec3<half_t, mediump>		mediump_hvec3;
+	
+	/// Vector of 4 medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tvec4<half_t, mediump>		mediump_hvec4;
+	
+	/// 2 * 2 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat2x2<half_t, mediump>	mediump_hmat2;
+	
+	/// 3 * 3 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat3x3<half_t, mediump>	mediump_hmat3;
+	
+	/// 4 * 4 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat4x4<half_t, mediump>	mediump_hmat4;
+	
+	/// 2 * 2 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat2x2<half_t, mediump>	mediump_hmat2x2;
+	
+	/// 2 * 3 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat2x3<half_t, mediump>	mediump_hmat2x3;
+	
+	/// 2 * 4 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat2x4<half_t, mediump>	mediump_hmat2x4;
+	
+	/// 3 * 2 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat3x2<half_t, mediump>	mediump_hmat3x2;
+	
+	/// 3 * 3 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat3x3<half_t, mediump>	mediump_hmat3x3;
+	
+	/// 3 * 4 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat3x4<half_t, mediump>	mediump_hmat3x4;
+	
+	/// 4 * 2 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat4x2<half_t, mediump>	mediump_hmat4x2;
+	
+	/// 4 * 3 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat4x3<half_t, mediump>	mediump_hmat4x3;
+	
+	/// 4 * 4 matrix of medium half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat4x4<half_t, mediump>	mediump_hmat4x4;
+	
+	
+	//////////////////////////////////////////////
+	// Low half precision floating-point numbers.
+	
+	/// Vector of 2 low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tvec2<half_t, lowp>		lowp_hvec2;
+	
+	/// Vector of 3 low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tvec3<half_t, lowp>		lowp_hvec3;
+	
+	/// Vector of 4 low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tvec4<half_t, lowp>		lowp_hvec4;
+	
+	/// 2 * 2 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat2x2<half_t, lowp>	lowp_hmat2;
+	
+	/// 3 * 3 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat3x3<half_t, lowp>	lowp_hmat3;
+	
+	/// 4 * 4 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat4x4<half_t, lowp>	lowp_hmat4;
+	
+	/// 2 * 2 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat2x2<half_t, lowp>	lowp_hmat2x2;
+	
+	/// 2 * 3 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat2x3<half_t, lowp>	lowp_hmat2x3;
+	
+	/// 2 * 4 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat2x4<half_t, lowp>	lowp_hmat2x4;
+	
+	/// 3 * 2 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat3x2<half_t, lowp>	lowp_hmat3x2;
+	
+	/// 3 * 3 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat3x3<half_t, lowp>	lowp_hmat3x3;
+	
+	/// 3 * 4 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat3x4<half_t, lowp>	lowp_hmat3x4;
+	
+	/// 4 * 2 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat4x2<half_t, lowp>	lowp_hmat4x2;
+	
+	/// 4 * 3 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat4x3<half_t, lowp>	lowp_hmat4x3;
+	
+	/// 4 * 4 matrix of low half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef detail::tmat4x4<half_t, lowp>	lowp_hmat4x4;
+	
+	
+	//////////////////////////////////////////////
+	// Default half precision floating-point numbers.
+	
+	/// Type for default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef half_t					half;
+	
+#if(!defined(GLM_PRECISION_HIGHP_HALF) && !defined(GLM_PRECISION_MEDIUMP_HALF) && !defined(GLM_PRECISION_LOWP_HALF))
+	//////////////////////////////////////////////
+	// Default half precision floating-point numbers.
+	
+	/// Vector of 2 default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hvec2		hvec2;
+	
+	/// Vector of 3 default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hvec3		hvec3;
+	
+	/// Vector of 4 default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hvec4		hvec4;
+	
+	/// 2 * 2 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat2x2		hmat2;
+	
+	/// 3 * 3 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat3x3		hmat3;
+	
+	/// 4 * 4 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat4x4		hmat4;
+	
+	/// 2 * 2 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat2x2		hmat2x2;
+	
+	/// 2 * 3 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat2x3		hmat2x3;
+	
+	/// 2 * 4 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat2x4		hmat2x4;
+	
+	/// 3 * 2 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat3x2		hmat3x2;
+	
+	/// 3 * 3 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat3x3		hmat3x3;
+	
+	/// 3 * 4 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat3x4		hmat3x4;
+	
+	/// 4 * 2 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat4x2		hmat4x2;
+	
+	/// 4 * 3 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat4x3		hmat4x3;
+	
+	/// 4 * 4 matrix of default half-precision floating-point numbers.
+	/// @see gtc_half_float
+	typedef mediump_hmat4x4		hmat4x4;
+	
+#elif(defined(GLM_PRECISION_HIGHP_HALF) && !defined(GLM_PRECISION_MEDIUMP_HALF) && !defined(GLM_PRECISION_LOWP_HALF))
+	typedef detail::tvec2<half_t, highp>		hvec2;
+	typedef detail::tvec3<half_t, highp>		hvec3;
+	typedef detail::tvec4<half_t, highp>		hvec4;
+	typedef detail::tmat2x2<half_t, highp>		hmat2;
+	typedef detail::tmat3x3<half_t, highp>		hmat3;
+	typedef detail::tmat4x4<half_t, highp>		hmat4;
+	typedef detail::tmat2x2<half_t, highp>		hmat2x2;
+	typedef detail::tmat2x3<half_t, highp>		hmat2x3;
+	typedef detail::tmat2x4<half_t, highp>		hmat2x4;
+	typedef detail::tmat3x2<half_t, highp>		hmat3x2;
+	typedef detail::tmat3x3<half_t, highp>		hmat3x3;
+	typedef detail::tmat3x4<half_t, highp>		hmat3x4;
+	typedef detail::tmat4x2<half_t, highp>		hmat4x2;
+	typedef detail::tmat4x3<half_t, highp>		hmat4x3;
+	typedef detail::tmat4x4<half_t, highp>		hmat4x4;
+	
+#elif(!defined(GLM_PRECISION_HIGHP_HALF) && defined(GLM_PRECISION_MEDIUMP_HALF) && !defined(GLM_PRECISION_LOWP_HALF))
+	typedef detail::tvec2<half_t, mediump>		hvec2;
+	typedef detail::tvec3<half_t, mediump>		hvec3;
+	typedef detail::tvec4<half_t, mediump>		hvec4;
+	typedef detail::tmat2x2<half_t, mediump>	hmat2;
+	typedef detail::tmat3x3<half_t, mediump>	hmat3;
+	typedef detail::tmat4x4<half_t, mediump>	hmat4;
+	typedef detail::tmat2x2<half_t, mediump>	hmat2x2;
+	typedef detail::tmat2x3<half_t, mediump>	hmat2x3;
+	typedef detail::tmat2x4<half_t, mediump>	hmat2x4;
+	typedef detail::tmat3x2<half_t, mediump>	hmat3x2;
+	typedef detail::tmat3x3<half_t, mediump>	hmat3x3;
+	typedef detail::tmat3x4<half_t, mediump>	hmat3x4;
+	typedef detail::tmat4x2<half_t, mediump>	hmat4x2;
+	typedef detail::tmat4x3<half_t, mediump>	hmat4x3;
+	typedef detail::tmat4x4<half_t, mediump>	hmat4x4;
+	
+#elif(!defined(GLM_PRECISION_HIGHP_HALF) && !defined(GLM_PRECISION_MEDIUMP_HALF) && defined(GLM_PRECISION_LOWP_HALF))	
+	typedef detail::tvec2<half_t, lowp>			hvec2;
+	typedef detail::tvec3<half_t, lowp>			hvec3;
+	typedef detail::tvec4<half_t, lowp>			hvec4;
+	typedef detail::tmat2x2<half_t, lowp>		hmat2;
+	typedef detail::tmat3x3<half_t, lowp>		hmat3;
+	typedef detail::tmat4x4<half_t, lowp>		hmat4;
+	typedef detail::tmat2x2<half_t, lowp>		hmat2x2;
+	typedef detail::tmat2x3<half_t, lowp>		hmat2x3;
+	typedef detail::tmat2x4<half_t, lowp>		hmat2x4;
+	typedef detail::tmat3x2<half_t, lowp>		hmat3x2;
+	typedef detail::tmat3x3<half_t, lowp>		hmat3x3;
+	typedef detail::tmat3x4<half_t, lowp>		hmat3x4;
+	typedef detail::tmat4x2<half_t, lowp>		hmat4x2;
+	typedef detail::tmat4x3<half_t, lowp>		hmat4x3;
+	typedef detail::tmat4x4<half_t, lowp>		hmat4x4;
+#endif
+	
 	/// Returns the absolute value of a half-precision floating-point value
 	/// @see gtc_half_float
 	half abs(half const & x);

+ 165 - 165
glm/gtc/half_float.inl

@@ -34,12 +34,12 @@ namespace detail
 	//////////////////////////////////////
 	// hvec2
 
-	GLM_FUNC_QUALIFIER tvec2<half>::size_type tvec2<half>::length() const
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::size_type tvec2<half, defaultp>::length() const
 	{
 		return 2;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half>::size_type tvec2<half>::value_size()
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::size_type tvec2<half, defaultp>::value_size()
 	{
 		return 2;
 	}
@@ -47,29 +47,29 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	GLM_FUNC_QUALIFIER half & tvec2<half>::operator[](tvec2<half>::size_type i)
+	GLM_FUNC_QUALIFIER half & tvec2<half, defaultp>::operator[](tvec2<half, defaultp>::size_type i)
 	{
-		assert(/*i >= tvec2<half>::size_type(0) && */i < tvec2<half>::value_size());
+		assert(i < this->length());
 		return (&x)[i];
 	}
 
-	GLM_FUNC_QUALIFIER half const & tvec2<half>::operator[](tvec2<half>::size_type i) const
+	GLM_FUNC_QUALIFIER half const & tvec2<half, defaultp>::operator[](tvec2<half, defaultp>::size_type i) const
 	{
-		assert(/*i >= tvec2<half>::size_type(0) && */i < tvec2<half>::value_size());
+		assert(i < this->length());
 		return (&x)[i];
 	}
 
 	//////////////////////////////////////
 	// Implicit basic constructors
 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2() :
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2() :
 		x(half(0.f)),
 		y(half(0.f))
 	{}
 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2
 	(
-		tvec2<half> const & v
+		tvec2<half, defaultp> const & v
 	) :
 		x(v.x),
 		y(v.y)
@@ -78,7 +78,7 @@ namespace detail
 	//////////////////////////////////////
 	// Explicit basic constructors
 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2
 	(
 		half const & s
 	) :
@@ -86,7 +86,7 @@ namespace detail
 		y(s)
 	{}
 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2
 	(
 		half const & s1,
 		half const & s2
@@ -98,9 +98,9 @@ namespace detail
 	//////////////////////////////////////
 	// Swizzle constructors
 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2
 	(
-		tref2<half> const & r
+		tref2<half, defaultp> const & r
 	) :
 		x(r.x),
 		y(r.y)
@@ -109,8 +109,8 @@ namespace detail
 	//////////////////////////////////////
 	// Convertion scalar constructors
 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2
 	(
 		U const & x
 	) :
@@ -118,10 +118,10 @@ namespace detail
 		y(half(x))
 	{}
 
-	template <typename U, typename V> 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2
+	template <typename U, typename V>
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2
 	(
-		U const & x, 
+		U const & x,
 		V const & y
 	) :
 		x(half(x)),
@@ -131,28 +131,28 @@ namespace detail
 	//////////////////////////////////////
 	// Convertion vector constructors
 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2
 	(
-		tvec2<U> const & v
+		tvec2<U, defaultp> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y))
 	{}
 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2
 	(	
-		tvec3<U> const & v
+		tvec3<U, defaultp> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y))
 	{}
 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec2<half>::tvec2
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>::tvec2
 	(
-		tvec4<U> const & v
+		tvec4<U, defaultp> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y))
@@ -161,9 +161,9 @@ namespace detail
 	//////////////////////////////////////
 	// Unary arithmetic operators
 
-	GLM_FUNC_QUALIFIER tvec2<half> & tvec2<half>::operator= 
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> & tvec2<half, defaultp>::operator=
 	(
-		tvec2<half> const & v
+		tvec2<half, defaultp> const & v
 	)
 	{
 		this->x = v.x;
@@ -171,7 +171,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> & tvec2<half>::operator+=
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> & tvec2<half, defaultp>::operator+=
 	(
 		half const & s
 	)
@@ -181,9 +181,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> & tvec2<half>::operator+=
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> & tvec2<half, defaultp>::operator+=
 	(
-		tvec2<half> const & v
+		tvec2<half, defaultp> const & v
 	)
 	{
 		this->x += v.x;
@@ -191,7 +191,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> & tvec2<half>::operator-=
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> & tvec2<half, defaultp>::operator-=
 	(
 		half const & s
 	)
@@ -201,9 +201,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> & tvec2<half>::operator-=
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> & tvec2<half, defaultp>::operator-=
 	(
-		tvec2<half> const & v
+		tvec2<half, defaultp> const & v
 	)
 	{
 		this->x -= v.x;
@@ -211,7 +211,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half>& tvec2<half>::operator*=
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>& tvec2<half, defaultp>::operator*=
 	(
 		half const & s
 	)
@@ -221,9 +221,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> & tvec2<half>::operator*=
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> & tvec2<half, defaultp>::operator*=
 	(
-		tvec2<half> const & v
+		tvec2<half, defaultp> const & v
 	)
 	{
 		this->x *= v.x;
@@ -231,7 +231,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> & tvec2<half>::operator/=
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> & tvec2<half, defaultp>::operator/=
 	(
 		half const & s
 	)
@@ -241,9 +241,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> & tvec2<half>::operator/=
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> & tvec2<half, defaultp>::operator/=
 	(
-		tvec2<half> const & v
+		tvec2<half, defaultp> const & v
 	)
 	{
 		this->x /= v.x;
@@ -251,14 +251,14 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> & tvec2<half>::operator++()
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> & tvec2<half, defaultp>::operator++()
 	{
 		++this->x;
 		++this->y;
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half>& tvec2<half>::operator--()
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp>& tvec2<half, defaultp>::operator--()
 	{
 		--this->x;
 		--this->y;
@@ -268,38 +268,38 @@ namespace detail
 	//////////////////////////////////////
 	// Swizzle operators
 
-	GLM_FUNC_QUALIFIER half tvec2<half>::swizzle(comp x) const
+	GLM_FUNC_QUALIFIER half tvec2<half, defaultp>::swizzle(comp x) const
 	{
 		return (*this)[x];
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> tvec2<half>::swizzle(comp x, comp y) const
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> tvec2<half, defaultp>::swizzle(comp x, comp y) const
 	{
-		return tvec2<half>(
+		return tvec2<half, defaultp>(
 			(*this)[x],
 			(*this)[y]);
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> tvec2<half>::swizzle(comp x, comp y, comp z) const
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> tvec2<half, defaultp>::swizzle(comp x, comp y, comp z) const
 	{
-		return tvec3<half>(
+		return tvec3<half, defaultp>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z]);
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half> tvec2<half>::swizzle(comp x, comp y, comp z, comp w) const
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp> tvec2<half, defaultp>::swizzle(comp x, comp y, comp z, comp w) const
 	{
-		return tvec4<half>(
+		return tvec4<half, defaultp>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z],
 			(*this)[w]);
 	}
 
-	GLM_FUNC_QUALIFIER tref2<half> tvec2<half>::swizzle(comp x, comp y)
+	GLM_FUNC_QUALIFIER tref2<half, defaultp> tvec2<half, defaultp>::swizzle(comp x, comp y)
 	{
-		return tref2<half>(
+		return tref2<half, defaultp>(
 			(*this)[x],
 			(*this)[y]);
 	}
@@ -307,12 +307,12 @@ namespace detail
 	//////////////////////////////////////
 	// hvec3
 
-	GLM_FUNC_QUALIFIER tvec3<half>::size_type tvec3<half>::length() const
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::size_type tvec3<half, defaultp>::length() const
 	{
 		return 3;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half>::size_type tvec3<half>::value_size()
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::size_type tvec3<half, defaultp>::value_size()
 	{
 		return 3;
 	}
@@ -320,22 +320,22 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	GLM_FUNC_QUALIFIER half & tvec3<half>::operator[]
+	GLM_FUNC_QUALIFIER half & tvec3<half, defaultp>::operator[]
 	(
-		tvec3<half>::size_type i
+		tvec3<half, defaultp>::size_type i
 	)
 	{
-		assert(/*i >= tvec3<half>::size_type(0) &&*/ i < tvec3<half>::value_size());
+		assert(i < this->length());
 
 		return (&x)[i];
 	}
 
-	GLM_FUNC_QUALIFIER half const & tvec3<half>::operator[]
+	GLM_FUNC_QUALIFIER half const & tvec3<half, defaultp>::operator[]
 	(
-		tvec3<half>::size_type i
+		tvec3<half, defaultp>::size_type i
 	) const
 	{
-		assert(/*i >= tvec3<half>::size_type(0) &&*/ i < tvec3<half>::value_size());
+		assert(i < this->length());
 
 		return (&x)[i];
 	}
@@ -343,15 +343,15 @@ namespace detail
 	//////////////////////////////////////
 	// Implicit basic constructors
 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3() :
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3() :
 		x(half(0)),
 		y(half(0)),
 		z(half(0))
 	{}
 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
-		tvec3<half> const & v
+		tvec3<half, defaultp> const & v
 	) :
 		x(v.x),
 		y(v.y),
@@ -361,7 +361,7 @@ namespace detail
 	//////////////////////////////////////
 	// Explicit basic constructors
 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
 		half const & s
 	) :
@@ -370,7 +370,7 @@ namespace detail
 		z(s)
 	{}
 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
 		half const & s0,
 		half const & s1,
@@ -384,9 +384,9 @@ namespace detail
 	//////////////////////////////////////
 	// Swizzle constructors
 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
-		tref3<half> const & r
+		tref3<half, defaultp> const & r
 	) :
 		x(r.x),
 		y(r.y),
@@ -396,8 +396,8 @@ namespace detail
 	//////////////////////////////////////
 	// Convertion scalar constructors
 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
 		U const & x
 	) :
@@ -407,7 +407,7 @@ namespace detail
 	{}
 
 	template <typename A, typename B, typename C>
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
 		A const & x,
 		B const & y,
@@ -421,10 +421,10 @@ namespace detail
 	//////////////////////////////////////
 	// Convertion vector constructors
 
-	template <typename A, typename B> 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	template <typename A, typename B>
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
-		tvec2<A> const & v, 
+		tvec2<A, defaultp> const & v,
 		B const & s
 	) :
 		x(half(v.x)),
@@ -432,31 +432,31 @@ namespace detail
 		z(half(s))
 	{}
 
-	template <typename A, typename B> 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	template <typename A, typename B>
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
-		A const & s, 
-		tvec2<B> const & v
+		A const & s,
+		tvec2<B, defaultp> const & v
 	) :
 		x(half(s)),
 		y(half(v.x)),
 		z(half(v.y))
 	{}
 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
-		tvec3<U> const & v
+		tvec3<U, defaultp> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y)),
 		z(half(v.z))
 	{}
 
-	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec3<half>::tvec3
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp>::tvec3
 	(
-		tvec4<U> const & v
+		tvec4<U, defaultp> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y)),
@@ -466,9 +466,9 @@ namespace detail
 	//////////////////////////////////////
 	// Unary arithmetic operators
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator=
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator=
 	(
-		tvec3<half> const & v
+		tvec3<half, defaultp> const & v
 	)
 	{
 		this->x = v.x;
@@ -477,7 +477,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator+=
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator+=
 	(
 		half const & s
 	)
@@ -488,9 +488,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator+=
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator+=
 	(
-		tvec3<half> const & v
+		tvec3<half, defaultp> const & v
 	)
 	{
 		this->x += v.x;
@@ -499,7 +499,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator-=
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator-=
 	(
 		half const & s
 	)
@@ -510,9 +510,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator-=
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator-=
 	(
-		tvec3<half> const & v
+		tvec3<half, defaultp> const & v
 	)
 	{
 		this->x -= v.x;
@@ -521,7 +521,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator*=
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator*=
 	(
 		half const & s
 	)
@@ -532,9 +532,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator*=
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator*=
 	(
-		tvec3<half> const & v
+		tvec3<half, defaultp> const & v
 	)
 	{
 		this->x *= v.x;
@@ -543,7 +543,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator/=
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator/=
 	(
 		half const & s
 	)
@@ -554,9 +554,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator/=
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator/=
 	(
-		tvec3<half> const & v
+		tvec3<half, defaultp> const & v
 	)
 	{
 		this->x /= v.x;
@@ -565,7 +565,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator++()
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator++()
 	{
 		++this->x;
 		++this->y;
@@ -573,7 +573,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> & tvec3<half>::operator--()
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> & tvec3<half, defaultp>::operator--()
 	{
 		--this->x;
 		--this->y;
@@ -584,38 +584,38 @@ namespace detail
 	//////////////////////////////////////
 	// Swizzle operators
 
-	GLM_FUNC_QUALIFIER half tvec3<half>::swizzle(comp x) const
+	GLM_FUNC_QUALIFIER half tvec3<half, defaultp>::swizzle(comp x) const
 	{
 		return (*this)[x];
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> tvec3<half>::swizzle(comp x, comp y) const
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> tvec3<half, defaultp>::swizzle(comp x, comp y) const
 	{
-		return tvec2<half>(
+		return tvec2<half, defaultp>(
 			(*this)[x],
 			(*this)[y]);
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> tvec3<half>::swizzle(comp x, comp y, comp z) const
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> tvec3<half, defaultp>::swizzle(comp x, comp y, comp z) const
 	{
-		return tvec3<half>(
+		return tvec3<half, defaultp>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z]);
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half> tvec3<half>::swizzle(comp x, comp y, comp z, comp w) const
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp> tvec3<half, defaultp>::swizzle(comp x, comp y, comp z, comp w) const
 	{
-		return tvec4<half>(
+		return tvec4<half, defaultp>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z],
 			(*this)[w]);
 	}
 
-	GLM_FUNC_QUALIFIER tref3<half> tvec3<half>::swizzle(comp x, comp y, comp z)
+	GLM_FUNC_QUALIFIER tref3<half, defaultp> tvec3<half, defaultp>::swizzle(comp x, comp y, comp z)
 	{
-		return tref3<half>(
+		return tref3<half, defaultp>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z]);
@@ -624,12 +624,12 @@ namespace detail
 	//////////////////////////////////////
 	// hvec4
 
-	GLM_FUNC_QUALIFIER tvec4<half>::size_type tvec4<half>::length() const
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::size_type tvec4<half, defaultp>::length() const
 	{
 		return 4;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>::size_type tvec4<half>::value_size()
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::size_type tvec4<half, defaultp>::value_size()
 	{
 		return 4;
 	}
@@ -637,22 +637,22 @@ namespace detail
 	//////////////////////////////////////
 	// Accesses
 
-	GLM_FUNC_QUALIFIER half & tvec4<half>::operator[]
+	GLM_FUNC_QUALIFIER half & tvec4<half, defaultp>::operator[]
 	(
-		tvec4<half>::size_type i
+		tvec4<half, defaultp>::size_type i
 	)
 	{
-		assert(/*i >= tvec4<half>::size_type(0) && */i < tvec4<half>::value_size());
+		assert(i < this->length());
 
 		return (&x)[i];
 	}
 
-	GLM_FUNC_QUALIFIER half const & tvec4<half>::operator[]
+	GLM_FUNC_QUALIFIER half const & tvec4<half, defaultp>::operator[]
 	(
-		tvec4<half>::size_type i
+		tvec4<half, defaultp>::size_type i
 	) const
 	{
-		assert(/*i >= tvec4<half>::size_type(0) && */i < tvec4<half>::value_size());
+		assert(i < this->length());
 
 		return (&x)[i];
 	}
@@ -660,16 +660,16 @@ namespace detail
 	//////////////////////////////////////
 	// Implicit basic constructors
 
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4() :
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4() :
 		x(half(0)),
 		y(half(0)),
 		z(half(0)),
 		w(half(0))
 	{}
 
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
-		tvec4<half> const & v
+		tvec4<half, defaultp> const & v
 	) :
 		x(v.x),
 		y(v.y),
@@ -680,7 +680,7 @@ namespace detail
 	//////////////////////////////////////
 	// Explicit basic constructors
 
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
 		half const & s
 	) :
@@ -690,7 +690,7 @@ namespace detail
 		w(s)
 	{}
 
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
 		half const & s1,
 		half const & s2,
@@ -706,9 +706,9 @@ namespace detail
 	//////////////////////////////////////
 	// Swizzle constructors
 
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
-		tref4<half> const & r
+		tref4<half, defaultp> const & r
 	) :
 		x(r.x),
 		y(r.y),
@@ -720,7 +720,7 @@ namespace detail
 	// Convertion scalar constructors
 
 	template <typename U> 
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
 		U const & x
 	) :
@@ -731,7 +731,7 @@ namespace detail
 	{}
 
 	template <typename A, typename B, typename C, typename D>
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
 		A const & x,
 		B const & y,
@@ -748,9 +748,9 @@ namespace detail
 	// Convertion vector constructors
 
 	template <typename A, typename B, typename C>
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
-		tvec2<A> const & v,
+		tvec2<A, defaultp> const & v,
 		B const & s1,
 		C const & s2
 	) :
@@ -761,10 +761,10 @@ namespace detail
 	{}
 
 	template <typename A, typename B, typename C>
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
 		A const & s1,
-		tvec2<B> const & v,
+		tvec2<B, defaultp> const & v,
 		C const & s2
 	) :
 		x(half(s1)),
@@ -774,11 +774,11 @@ namespace detail
 	{}
 
 	template <typename A, typename B, typename C>
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
 		A const & s1,
 		B const & s2,
-		tvec2<C> const & v
+		tvec2<C, defaultp> const & v
 	) :
 		x(half(s1)),
 		y(half(s2)),
@@ -787,9 +787,9 @@ namespace detail
 	{}
 
 	template <typename A, typename B>
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
-		tvec3<A> const & v,
+		tvec3<A, defaultp> const & v,
 		B const & s
 	) :
 		x(half(v.x)),
@@ -799,10 +799,10 @@ namespace detail
 	{}
 
 	template <typename A, typename B>
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
 		A const & s,
-		tvec3<B> const & v
+		tvec3<B, defaultp> const & v
 	) :
 		x(half(s)),
 		y(half(v.x)),
@@ -811,10 +811,10 @@ namespace detail
 	{}
 
 	template <typename A, typename B>
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
-		tvec2<A> const & v1,
-		tvec2<B> const & v2
+		tvec2<A, defaultp> const & v1,
+		tvec2<B, defaultp> const & v2
 	) :
 		x(half(v1.x)),
 		y(half(v1.y)),
@@ -823,9 +823,9 @@ namespace detail
 	{}
 
 	template <typename U>
-	GLM_FUNC_QUALIFIER tvec4<half>::tvec4
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>::tvec4
 	(
-		tvec4<U> const & v
+		tvec4<U, defaultp> const & v
 	) :
 		x(half(v.x)),
 		y(half(v.y)),
@@ -836,9 +836,9 @@ namespace detail
 	//////////////////////////////////////
 	// Unary arithmetic operators
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator=
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator=
 	(
-		tvec4<half> const & v
+		tvec4<half, defaultp> const & v
 	)
 	{
 		this->x = v.x;
@@ -848,7 +848,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator+=
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator+=
 	(
 		half const & s
 	)
@@ -860,9 +860,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator+=
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator+=
 	(
-		tvec4<half> const & v
+		tvec4<half, defaultp> const & v
 	)
 	{
 		this->x += v.x;
@@ -872,7 +872,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator-=
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator-=
 	(
 		half const & s
 	)
@@ -884,9 +884,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator-=
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator-=
 	(
-		tvec4<half> const & v
+		tvec4<half, defaultp> const & v
 	)
 	{
 		this->x -= v.x;
@@ -896,7 +896,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator*=
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator*=
 	(
 		half const & s
 	)
@@ -908,9 +908,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator*=
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator*=
 	(
-		tvec4<half> const & v
+		tvec4<half, defaultp> const & v
 	)
 	{
 		this->x *= v.x;
@@ -920,7 +920,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator/=
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator/=
 	(
 		half const & s
 	)
@@ -932,9 +932,9 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator/=
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator/=
 	(
-		tvec4<half> const & v
+		tvec4<half, defaultp> const & v
 	)
 	{
 		this->x /= v.x;
@@ -944,7 +944,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator++()
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator++()
 	{
 		++this->x;
 		++this->y;
@@ -953,7 +953,7 @@ namespace detail
 		return *this;
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half>& tvec4<half>::operator--()
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp>& tvec4<half, defaultp>::operator--()
 	{
 		--this->x;
 		--this->y;
@@ -965,38 +965,38 @@ namespace detail
 	//////////////////////////////////////
 	// Swizzle operators
 
-	GLM_FUNC_QUALIFIER half tvec4<half>::swizzle(comp x) const
+	GLM_FUNC_QUALIFIER half tvec4<half, defaultp>::swizzle(comp x) const
 	{
 		return (*this)[x];
 	}
 
-	GLM_FUNC_QUALIFIER tvec2<half> tvec4<half>::swizzle(comp x, comp y) const
+	GLM_FUNC_QUALIFIER tvec2<half, defaultp> tvec4<half, defaultp>::swizzle(comp x, comp y) const
 	{
-		return tvec2<half>(
+		return tvec2<half, defaultp>(
 			(*this)[x],
 			(*this)[y]);
 	}
 
-	GLM_FUNC_QUALIFIER tvec3<half> tvec4<half>::swizzle(comp x, comp y, comp z) const
+	GLM_FUNC_QUALIFIER tvec3<half, defaultp> tvec4<half, defaultp>::swizzle(comp x, comp y, comp z) const
 	{
-		return tvec3<half>(
+		return tvec3<half, defaultp>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z]);
 	}
 
-	GLM_FUNC_QUALIFIER tvec4<half> tvec4<half>::swizzle(comp x, comp y, comp z, comp w) const
+	GLM_FUNC_QUALIFIER tvec4<half, defaultp> tvec4<half, defaultp>::swizzle(comp x, comp y, comp z, comp w) const
 	{
-		return tvec4<half>(
+		return tvec4<half, defaultp>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z],
 			(*this)[w]);
 	}
 
-	GLM_FUNC_QUALIFIER tref4<half> tvec4<half>::swizzle(comp x, comp y, comp z, comp w)
+	GLM_FUNC_QUALIFIER tref4<half, defaultp> tvec4<half, defaultp>::swizzle(comp x, comp y, comp z, comp w)
 	{
-		return tref4<half>(
+		return tref4<half, defaultp>(
 			(*this)[x],
 			(*this)[y],
 			(*this)[z],

+ 73 - 73
glm/gtc/matrix_integer.hpp

@@ -51,300 +51,300 @@ namespace glm
 
 	/// High-precision signed integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<highp_int>				highp_imat2;	
+	typedef detail::tmat2x2<int, highp>				highp_imat2;
 
 	/// High-precision signed integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<highp_int>				highp_imat3;
+	typedef detail::tmat3x3<int, highp>				highp_imat3;
 
 	/// High-precision signed integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<highp_int>				highp_imat4;
+	typedef detail::tmat4x4<int, highp>				highp_imat4;
 
 	/// High-precision signed integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<highp_int>				highp_imat2x2;
+	typedef detail::tmat2x2<int, highp>				highp_imat2x2;
 
 	/// High-precision signed integer 2x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x3<highp_int>				highp_imat2x3;
+	typedef detail::tmat2x3<int, highp>				highp_imat2x3;
 
 	/// High-precision signed integer 2x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x4<highp_int>				highp_imat2x4;
+	typedef detail::tmat2x4<int, highp>				highp_imat2x4;
 
 	/// High-precision signed integer 3x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x2<highp_int>				highp_imat3x2;
+	typedef detail::tmat3x2<int, highp>				highp_imat3x2;
 
 	/// High-precision signed integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<highp_int>				highp_imat3x3;
+	typedef detail::tmat3x3<int, highp>				highp_imat3x3;
 
 	/// High-precision signed integer 3x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x4<highp_int>				highp_imat3x4;
+	typedef detail::tmat3x4<int, highp>				highp_imat3x4;
 
 	/// High-precision signed integer 4x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x2<highp_int>				highp_imat4x2;
+	typedef detail::tmat4x2<int, highp>				highp_imat4x2;
 
 	/// High-precision signed integer 4x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x3<highp_int>				highp_imat4x3;
+	typedef detail::tmat4x3<int, highp>				highp_imat4x3;
 
 	/// High-precision signed integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<highp_int>				highp_imat4x4;
+	typedef detail::tmat4x4<int, highp>				highp_imat4x4;
 
 
 	/// Medium-precision signed integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<mediump_int>			mediump_imat2;
+	typedef detail::tmat2x2<int, mediump>			mediump_imat2;
 
 	/// Medium-precision signed integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<mediump_int>			mediump_imat3;
+	typedef detail::tmat3x3<int, mediump>			mediump_imat3;
 
 	/// Medium-precision signed integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<mediump_int>			mediump_imat4;
+	typedef detail::tmat4x4<int, mediump>			mediump_imat4;
 
 
 	/// Medium-precision signed integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<mediump_int>			mediump_imat2x2;
+	typedef detail::tmat2x2<int, mediump>			mediump_imat2x2;
 
 	/// Medium-precision signed integer 2x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x3<mediump_int>			mediump_imat2x3;
+	typedef detail::tmat2x3<int, mediump>			mediump_imat2x3;
 
 	/// Medium-precision signed integer 2x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x4<mediump_int>			mediump_imat2x4;
+	typedef detail::tmat2x4<int, mediump>			mediump_imat2x4;
 
 	/// Medium-precision signed integer 3x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x2<mediump_int>			mediump_imat3x2;
+	typedef detail::tmat3x2<int, mediump>			mediump_imat3x2;
 
 	/// Medium-precision signed integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<mediump_int>			mediump_imat3x3;
+	typedef detail::tmat3x3<int, mediump>			mediump_imat3x3;
 
 	/// Medium-precision signed integer 3x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x4<mediump_int>			mediump_imat3x4;
+	typedef detail::tmat3x4<int, mediump>			mediump_imat3x4;
 
 	/// Medium-precision signed integer 4x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x2<mediump_int>			mediump_imat4x2;
+	typedef detail::tmat4x2<int, mediump>			mediump_imat4x2;
 
 	/// Medium-precision signed integer 4x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x3<mediump_int>			mediump_imat4x3;
+	typedef detail::tmat4x3<int, mediump>			mediump_imat4x3;
 
 	/// Medium-precision signed integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<mediump_int>			mediump_imat4x4;
+	typedef detail::tmat4x4<int, mediump>			mediump_imat4x4;
 
 
 	/// Low-precision signed integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<lowp_int>				lowp_imat2;
+	typedef detail::tmat2x2<int, lowp>				lowp_imat2;
 	
 	/// Low-precision signed integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<lowp_int>				lowp_imat3;
+	typedef detail::tmat3x3<int, lowp>				lowp_imat3;
 
 	/// Low-precision signed integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<lowp_int>				lowp_imat4;
+	typedef detail::tmat4x4<int, lowp>				lowp_imat4;
 
 
 	/// Low-precision signed integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<lowp_int>				lowp_imat2x2;
+	typedef detail::tmat2x2<int, lowp>				lowp_imat2x2;
 
 	/// Low-precision signed integer 2x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x3<lowp_int>				lowp_imat2x3;
+	typedef detail::tmat2x3<int, lowp>				lowp_imat2x3;
 
 	/// Low-precision signed integer 2x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x4<lowp_int>				lowp_imat2x4;
+	typedef detail::tmat2x4<int, lowp>				lowp_imat2x4;
 
 	/// Low-precision signed integer 3x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x2<lowp_int>				lowp_imat3x2;
+	typedef detail::tmat3x2<int, lowp>				lowp_imat3x2;
 
 	/// Low-precision signed integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<lowp_int>				lowp_imat3x3;
+	typedef detail::tmat3x3<int, lowp>				lowp_imat3x3;
 
 	/// Low-precision signed integer 3x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x4<lowp_int>				lowp_imat3x4;
+	typedef detail::tmat3x4<int, lowp>				lowp_imat3x4;
 
 	/// Low-precision signed integer 4x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x2<lowp_int>				lowp_imat4x2;
+	typedef detail::tmat4x2<int, lowp>				lowp_imat4x2;
 
 	/// Low-precision signed integer 4x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x3<lowp_int>				lowp_imat4x3;
+	typedef detail::tmat4x3<int, lowp>				lowp_imat4x3;
 
 	/// Low-precision signed integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<lowp_int>				lowp_imat4x4;
+	typedef detail::tmat4x4<int, lowp>				lowp_imat4x4;
 
 
 	/// High-precision unsigned integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<highp_uint>				highp_umat2;	
+	typedef detail::tmat2x2<uint, highp>				highp_umat2;	
 
 	/// High-precision unsigned integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<highp_uint>				highp_umat3;
+	typedef detail::tmat3x3<uint, highp>				highp_umat3;
 
 	/// High-precision unsigned integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<highp_uint>				highp_umat4;
+	typedef detail::tmat4x4<uint, highp>				highp_umat4;
 
 	/// High-precision unsigned integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<highp_uint>				highp_umat2x2;
+	typedef detail::tmat2x2<uint, highp>				highp_umat2x2;
 
 	/// High-precision unsigned integer 2x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x3<highp_uint>				highp_umat2x3;
+	typedef detail::tmat2x3<uint, highp>				highp_umat2x3;
 
 	/// High-precision unsigned integer 2x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x4<highp_uint>				highp_umat2x4;
+	typedef detail::tmat2x4<uint, highp>				highp_umat2x4;
 
 	/// High-precision unsigned integer 3x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x2<highp_uint>				highp_umat3x2;
+	typedef detail::tmat3x2<uint, highp>				highp_umat3x2;
 
 	/// High-precision unsigned integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<highp_uint>				highp_umat3x3;
+	typedef detail::tmat3x3<uint, highp>				highp_umat3x3;
 
 	/// High-precision unsigned integer 3x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x4<highp_uint>				highp_umat3x4;
+	typedef detail::tmat3x4<uint, highp>				highp_umat3x4;
 
 	/// High-precision unsigned integer 4x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x2<highp_uint>				highp_umat4x2;
+	typedef detail::tmat4x2<uint, highp>				highp_umat4x2;
 
 	/// High-precision unsigned integer 4x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x3<highp_uint>				highp_umat4x3;
+	typedef detail::tmat4x3<uint, highp>				highp_umat4x3;
 
 	/// High-precision unsigned integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<highp_uint>				highp_umat4x4;
+	typedef detail::tmat4x4<uint, highp>				highp_umat4x4;
 
 
 	/// Medium-precision unsigned integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<mediump_uint>			mediump_umat2;
+	typedef detail::tmat2x2<uint, mediump>			mediump_umat2;
 
 	/// Medium-precision unsigned integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<mediump_uint>			mediump_umat3;
+	typedef detail::tmat3x3<uint, mediump>			mediump_umat3;
 
 	/// Medium-precision unsigned integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<mediump_uint>			mediump_umat4;
+	typedef detail::tmat4x4<uint, mediump>			mediump_umat4;
 
 
 	/// Medium-precision unsigned integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<mediump_uint>			mediump_umat2x2;
+	typedef detail::tmat2x2<uint, mediump>			mediump_umat2x2;
 
 	/// Medium-precision unsigned integer 2x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x3<mediump_uint>			mediump_umat2x3;
+	typedef detail::tmat2x3<uint, mediump>			mediump_umat2x3;
 
 	/// Medium-precision unsigned integer 2x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x4<mediump_uint>			mediump_umat2x4;
+	typedef detail::tmat2x4<uint, mediump>			mediump_umat2x4;
 
 	/// Medium-precision unsigned integer 3x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x2<mediump_uint>			mediump_umat3x2;
+	typedef detail::tmat3x2<uint, mediump>			mediump_umat3x2;
 
 	/// Medium-precision unsigned integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<mediump_uint>			mediump_umat3x3;
+	typedef detail::tmat3x3<uint, mediump>			mediump_umat3x3;
 
 	/// Medium-precision unsigned integer 3x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x4<mediump_uint>			mediump_umat3x4;
+	typedef detail::tmat3x4<uint, mediump>			mediump_umat3x4;
 
 	/// Medium-precision unsigned integer 4x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x2<mediump_uint>			mediump_umat4x2;
+	typedef detail::tmat4x2<uint, mediump>			mediump_umat4x2;
 
 	/// Medium-precision unsigned integer 4x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x3<mediump_uint>			mediump_umat4x3;
+	typedef detail::tmat4x3<uint, mediump>			mediump_umat4x3;
 
 	/// Medium-precision unsigned integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<mediump_uint>			mediump_umat4x4;
+	typedef detail::tmat4x4<uint, mediump>			mediump_umat4x4;
 
 
 	/// Low-precision unsigned integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<lowp_uint>				lowp_umat2;
+	typedef detail::tmat2x2<uint, lowp>				lowp_umat2;
 	
 	/// Low-precision unsigned integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<lowp_uint>				lowp_umat3;
+	typedef detail::tmat3x3<uint, lowp>				lowp_umat3;
 
 	/// Low-precision unsigned integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<lowp_uint>				lowp_umat4;
+	typedef detail::tmat4x4<uint, lowp>				lowp_umat4;
 
 
 	/// Low-precision unsigned integer 2x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x2<lowp_uint>				lowp_umat2x2;
+	typedef detail::tmat2x2<uint, lowp>				lowp_umat2x2;
 
 	/// Low-precision unsigned integer 2x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x3<lowp_uint>				lowp_umat2x3;
+	typedef detail::tmat2x3<uint, lowp>				lowp_umat2x3;
 
 	/// Low-precision unsigned integer 2x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat2x4<lowp_uint>				lowp_umat2x4;
+	typedef detail::tmat2x4<uint, lowp>				lowp_umat2x4;
 
 	/// Low-precision unsigned integer 3x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x2<lowp_uint>				lowp_umat3x2;
+	typedef detail::tmat3x2<uint, lowp>				lowp_umat3x2;
 
 	/// Low-precision unsigned integer 3x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x3<lowp_uint>				lowp_umat3x3;
+	typedef detail::tmat3x3<uint, lowp>				lowp_umat3x3;
 
 	/// Low-precision unsigned integer 3x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat3x4<lowp_uint>				lowp_umat3x4;
+	typedef detail::tmat3x4<uint, lowp>				lowp_umat3x4;
 
 	/// Low-precision unsigned integer 4x2 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x2<lowp_uint>				lowp_umat4x2;
+	typedef detail::tmat4x2<uint, lowp>				lowp_umat4x2;
 
 	/// Low-precision unsigned integer 4x3 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x3<lowp_uint>				lowp_umat4x3;
+	typedef detail::tmat4x3<uint, lowp>				lowp_umat4x3;
 
 	/// Low-precision unsigned integer 4x4 matrix.
 	/// @see gtc_matrix_integer
-	typedef detail::tmat4x4<lowp_uint>				lowp_umat4x4;
+	typedef detail::tmat4x4<uint, lowp>				lowp_umat4x4;
 
 #if(defined(GLM_PRECISION_HIGHP_INT))
 	typedef highp_imat2								imat2;
@@ -451,7 +451,7 @@ namespace glm
 	typedef lowp_umat4x4							umat4x4;
 #else //if(defined(GLM_PRECISION_MEDIUMP_UINT))
 	
-    /// Unsigned integer 2x2 matrix.
+	/// Unsigned integer 2x2 matrix.
 	/// @see gtc_matrix_integer
 	typedef mediump_umat2							umat2;
 

+ 50 - 50
glm/gtc/matrix_inverse.inl

@@ -28,43 +28,43 @@
 
 namespace glm
 {
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> affineInverse
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> affineInverse
 	(
-		detail::tmat3x3<T> const & m
+		detail::tmat3x3<T, P> const & m
 	)
 	{
-		detail::tmat3x3<T> Result(m);
-		Result[2] = detail::tvec3<T>(0, 0, 1);
+		detail::tmat3x3<T, P> Result(m);
+		Result[2] = detail::tvec3<T, P>(0, 0, 1);
 		Result = transpose(Result);
-		detail::tvec3<T> Translation = Result * detail::tvec3<T>(-detail::tvec2<T>(m[2]), m[2][2]);
+		detail::tvec3<T, P> Translation = Result * detail::tvec3<T, P>(-detail::tvec2<T, P>(m[2]), m[2][2]);
 		Result[2] = Translation;
 		return Result;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> affineInverse
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> affineInverse
 	(
-		detail::tmat4x4<T> const & m
+		detail::tmat4x4<T, P> const & m
 	)
 	{
-		detail::tmat4x4<T> Result(m);
-		Result[3] = detail::tvec4<T>(0, 0, 0, 1);
+		detail::tmat4x4<T, P> Result(m);
+		Result[3] = detail::tvec4<T, P>(0, 0, 0, 1);
 		Result = transpose(Result);
-		detail::tvec4<T> Translation = Result * detail::tvec4<T>(-detail::tvec3<T>(m[3]), m[3][3]);
+		detail::tvec4<T, P> Translation = Result * detail::tvec4<T, P>(-detail::tvec3<T, P>(m[3]), m[3][3]);
 		Result[3] = Translation;
 		return Result;
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat2x2<valType> inverseTranspose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, P> inverseTranspose
 	(
-		detail::tmat2x2<valType> const & m
+		detail::tmat2x2<T, P> const & m
 	)
 	{
-		valType Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1];
+		T Determinant = m[0][0] * m[1][1] - m[1][0] * m[0][1];
 
-		detail::tmat2x2<valType> Inverse(
+		detail::tmat2x2<T, P> Inverse(
 			+ m[1][1] / Determinant,
 			- m[0][1] / Determinant,
 			- m[1][0] / Determinant,
@@ -73,18 +73,18 @@ namespace glm
 		return Inverse;
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat3x3<valType> inverseTranspose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> inverseTranspose
 	(
-		detail::tmat3x3<valType> const & m
+		detail::tmat3x3<T, P> const & m
 	)
 	{
-		valType Determinant = 
+		T Determinant =
 			+ m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1])
 			- m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0])
 			+ m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]);
 
-		detail::tmat3x3<valType> Inverse;
+		detail::tmat3x3<T, P> Inverse;
 		Inverse[0][0] = + (m[1][1] * m[2][2] - m[2][1] * m[1][2]);
 		Inverse[0][1] = - (m[1][0] * m[2][2] - m[2][0] * m[1][2]);
 		Inverse[0][2] = + (m[1][0] * m[2][1] - m[2][0] * m[1][1]);
@@ -99,33 +99,33 @@ namespace glm
 		return Inverse;
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> inverseTranspose
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> inverseTranspose
 	(
-		detail::tmat4x4<valType> const & m
+		detail::tmat4x4<T, P> const & m
 	)
 	{
-		valType SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
-		valType SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
-		valType SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
-		valType SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
-		valType SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
-		valType SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
-		valType SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
-		valType SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
-		valType SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
-		valType SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
-		valType SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
-		valType SubFactor11 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
-		valType SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
-		valType SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
-		valType SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
-		valType SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
-		valType SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
-		valType SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
-		valType SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
-
-		detail::tmat4x4<valType> Inverse;
+		T SubFactor00 = m[2][2] * m[3][3] - m[3][2] * m[2][3];
+		T SubFactor01 = m[2][1] * m[3][3] - m[3][1] * m[2][3];
+		T SubFactor02 = m[2][1] * m[3][2] - m[3][1] * m[2][2];
+		T SubFactor03 = m[2][0] * m[3][3] - m[3][0] * m[2][3];
+		T SubFactor04 = m[2][0] * m[3][2] - m[3][0] * m[2][2];
+		T SubFactor05 = m[2][0] * m[3][1] - m[3][0] * m[2][1];
+		T SubFactor06 = m[1][2] * m[3][3] - m[3][2] * m[1][3];
+		T SubFactor07 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+		T SubFactor08 = m[1][1] * m[3][2] - m[3][1] * m[1][2];
+		T SubFactor09 = m[1][0] * m[3][3] - m[3][0] * m[1][3];
+		T SubFactor10 = m[1][0] * m[3][2] - m[3][0] * m[1][2];
+		T SubFactor11 = m[1][1] * m[3][3] - m[3][1] * m[1][3];
+		T SubFactor12 = m[1][0] * m[3][1] - m[3][0] * m[1][1];
+		T SubFactor13 = m[1][2] * m[2][3] - m[2][2] * m[1][3];
+		T SubFactor14 = m[1][1] * m[2][3] - m[2][1] * m[1][3];
+		T SubFactor15 = m[1][1] * m[2][2] - m[2][1] * m[1][2];
+		T SubFactor16 = m[1][0] * m[2][3] - m[2][0] * m[1][3];
+		T SubFactor17 = m[1][0] * m[2][2] - m[2][0] * m[1][2];
+		T SubFactor18 = m[1][0] * m[2][1] - m[2][0] * m[1][1];
+
+		detail::tmat4x4<T, P> Inverse;
 		Inverse[0][0] = + (m[1][1] * SubFactor00 - m[1][2] * SubFactor01 + m[1][3] * SubFactor02);
 		Inverse[0][1] = - (m[1][0] * SubFactor00 - m[1][2] * SubFactor03 + m[1][3] * SubFactor04);
 		Inverse[0][2] = + (m[1][0] * SubFactor01 - m[1][1] * SubFactor03 + m[1][3] * SubFactor05);
@@ -146,10 +146,10 @@ namespace glm
 		Inverse[3][2] = - (m[0][0] * SubFactor14 - m[0][1] * SubFactor16 + m[0][3] * SubFactor18);
 		Inverse[3][3] = + (m[0][0] * SubFactor15 - m[0][1] * SubFactor17 + m[0][2] * SubFactor18);
 
-		valType Determinant = 
-			+ m[0][0] * Inverse[0][0] 
-			+ m[0][1] * Inverse[0][1] 
-			+ m[0][2] * Inverse[0][2] 
+		T Determinant =
+			+ m[0][0] * Inverse[0][0]
+			+ m[0][1] * Inverse[0][1]
+			+ m[0][2] * Inverse[0][2]
 			+ m[0][3] * Inverse[0][3];
 
 		Inverse /= Determinant;

+ 84 - 84
glm/gtc/matrix_transform.hpp

@@ -76,12 +76,12 @@ namespace glm
 	/// @see gtc_matrix_transform
 	/// @see gtx_transform
 	/// @see - translate(T x, T y, T z)
-	/// @see - translate(detail::tmat4x4<T> const & m, T x, T y, T z)
-	/// @see - translate(detail::tvec3<T> const & v)
-	template <typename T> 
-	detail::tmat4x4<T> translate(
-		detail::tmat4x4<T> const & m,
-		detail::tvec3<T> const & v);
+	/// @see - translate(detail::tmat4x4<T, P> const & m, T x, T y, T z)
+	/// @see - translate(detail::tvec3<T, P> const & v)
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> translate(
+		detail::tmat4x4<T, P> const & m,
+		detail::tvec3<T, P> const & v);
 		
 	/// Builds a rotation 4 * 4 matrix created from an axis vector and an angle. 
 	/// 
@@ -92,13 +92,13 @@ namespace glm
 	/// @see gtc_matrix_transform
 	/// @see gtx_transform
 	/// @see - rotate(T angle, T x, T y, T z) 
-	/// @see - rotate(detail::tmat4x4<T> const & m, T angle, T x, T y, T z) 
-	/// @see - rotate(T angle, detail::tvec3<T> const & v) 
-	template <typename T> 
-	detail::tmat4x4<T> rotate(
-		detail::tmat4x4<T> const & m,
-		T const & angle, 
-		detail::tvec3<T> const & axis);
+	/// @see - rotate(detail::tmat4x4<T, P> const & m, T angle, T x, T y, T z) 
+	/// @see - rotate(T angle, detail::tvec3<T, P> const & v) 
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> rotate(
+		detail::tmat4x4<T, P> const & m,
+		T const & angle,
+		detail::tvec3<T, P> const & axis);
 
 	/// Builds a scale 4 * 4 matrix created from 3 scalars. 
 	/// 
@@ -108,12 +108,12 @@ namespace glm
 	/// @see gtc_matrix_transform
 	/// @see gtx_transform
 	/// @see - scale(T x, T y, T z) scale(T const & x, T const & y, T const & z)
-	/// @see - scale(detail::tmat4x4<T> const & m, T x, T y, T z)
-	/// @see - scale(detail::tvec3<T> const & v)
-	template <typename T> 
-	detail::tmat4x4<T> scale(
-		detail::tmat4x4<T> const & m,
-		detail::tvec3<T> const & v);
+	/// @see - scale(detail::tmat4x4<T, P> const & m, T x, T y, T z)
+	/// @see - scale(detail::tvec3<T, P> const & v)
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> scale(
+		detail::tmat4x4<T, P> const & m,
+		detail::tvec3<T, P> const & v);
 
 	/// Creates a matrix for an orthographic parallel viewing volume.
 	/// 
@@ -126,13 +126,13 @@ namespace glm
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
 	/// @see - glm::ortho(T const & left, T const & right, T const & bottom, T const & top)
-	template <typename T> 
-	detail::tmat4x4<T> ortho(
-		T const & left, 
-		T const & right, 
-		T const & bottom, 
-		T const & top, 
-		T const & zNear, 
+	template <typename T>
+	detail::tmat4x4<T, defaultp> ortho(
+		T const & left,
+		T const & right,
+		T const & bottom,
+		T const & top,
+		T const & zNear,
 		T const & zFar);
 
 	/// Creates a matrix for projecting two-dimensional coordinates onto the screen.
@@ -144,11 +144,11 @@ namespace glm
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
 	/// @see - glm::ortho(T const & left, T const & right, T const & bottom, T const & top, T const & zNear, T const & zFar)
-	template <typename T> 
-	detail::tmat4x4<T> ortho(
-		T const & left, 
-		T const & right, 
-		T const & bottom, 
+	template <typename T>
+	detail::tmat4x4<T, defaultp> ortho(
+		T const & left,
+		T const & right,
+		T const & bottom,
 		T const & top);
 
 	/// Creates a frustum matrix.
@@ -161,13 +161,13 @@ namespace glm
 	/// @param far 
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
-	template <typename T> 
-	detail::tmat4x4<T> frustum(
-		T const & left, 
-		T const & right, 
-		T const & bottom, 
-		T const & top, 
-		T const & near, 
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> frustum(
+		T const & left,
+		T const & right,
+		T const & bottom,
+		T const & top,
+		T const & near,
 		T const & far);
 
 	/// Creates a matrix for a symetric perspective-view frustum.
@@ -178,11 +178,11 @@ namespace glm
 	/// @param far 
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
-	template <typename T> 
-	detail::tmat4x4<T> perspective(
-		T const & fovy, 
-		T const & aspect, 
-		T const & near, 
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> perspective(
+		T const & fovy,
+		T const & aspect,
+		T const & near,
 		T const & far);
 
 	/// Builds a perspective projection matrix based on a field of view.
@@ -194,13 +194,13 @@ namespace glm
 	/// @param far 
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
-	template <typename valType> 
-	detail::tmat4x4<valType> perspectiveFov(
-		valType const & fov, 
-		valType const & width, 
-		valType const & height, 
-		valType const & near, 
-		valType const & far);
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> perspectiveFov(
+		T const & fov,
+		T const & width,
+		T const & height,
+		T const & near,
+		T const & far);
 
 	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite.
 	/// 
@@ -209,8 +209,8 @@ namespace glm
 	/// @param near 
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
-	template <typename T> 
-	detail::tmat4x4<T> infinitePerspective(
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> infinitePerspective(
 		T fovy, T aspect, T near);
 
 	/// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite for graphics hardware that doesn't support depth clamping.
@@ -220,8 +220,8 @@ namespace glm
 	/// @param near 
 	/// @tparam T Value type used to build the matrix. Currently supported: half (not recommanded), float or double.
 	/// @see gtc_matrix_transform
-	template <typename T> 
-	detail::tmat4x4<T> tweakedInfinitePerspective(
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> tweakedInfinitePerspective(
 		T fovy, T aspect, T near);
 
 	/// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates.
@@ -233,55 +233,55 @@ namespace glm
 	/// @tparam T Native type used for the computation. Currently supported: half (not recommanded), float or double.
 	/// @tparam U Currently supported: Floating-point types and integer types.
 	/// @see gtc_matrix_transform
-	template <typename T, typename U> 
-	detail::tvec3<T> project(
-		detail::tvec3<T> const & obj, 
-		detail::tmat4x4<T> const & model, 
-		detail::tmat4x4<T> const & proj, 
-		detail::tvec4<U> const & viewport);
+	template <typename T, typename U, precision P>
+	detail::tvec3<T, P> project(
+		detail::tvec3<T, P> const & obj,
+		detail::tmat4x4<T, P> const & model,
+		detail::tmat4x4<T, P> const & proj,
+		detail::tvec4<U, P> const & viewport);
 
 	/// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
-	/// 
-	/// @param win 
-	/// @param model 
+	///
+	/// @param win
+	/// @param model
 	/// @param proj
-	/// @param viewport 
+	/// @param viewport
 	/// @tparam T Native type used for the computation. Currently supported: half (not recommanded), float or double.
 	/// @tparam U Currently supported: Floating-point types and integer types.
 	/// @see gtc_matrix_transform
-	template <typename T, typename U> 
-	detail::tvec3<T> unProject(
-		detail::tvec3<T> const & win, 
-		detail::tmat4x4<T> const & model, 
-		detail::tmat4x4<T> const & proj, 
-		detail::tvec4<U> const & viewport);
+	template <typename T, typename U, precision P>
+	detail::tvec3<T, P> unProject(
+		detail::tvec3<T, P> const & win,
+		detail::tmat4x4<T, P> const & model,
+		detail::tmat4x4<T, P> const & proj,
+		detail::tvec4<U, P> const & viewport);
 
 	/// Define a picking region
-	/// 
-	/// @param center 
-	/// @param delta 
+	///
+	/// @param center
+	/// @param delta
 	/// @param viewport
 	/// @tparam T Native type used for the computation. Currently supported: half (not recommanded), float or double.
 	/// @tparam U Currently supported: Floating-point types and integer types.
 	/// @see gtc_matrix_transform
-	template <typename T, typename U> 
-	detail::tmat4x4<T> pickMatrix(
-		detail::tvec2<T> const & center, 
-		detail::tvec2<T> const & delta, 
-		detail::tvec4<U> const & viewport);
+	template <typename T, precision P, typename U>
+	detail::tmat4x4<T, P> pickMatrix(
+		detail::tvec2<T, P> const & center,
+		detail::tvec2<T, P> const & delta,
+		detail::tvec4<U, P> const & viewport);
 
 	/// Build a look at view matrix.
-	/// 
+	///
 	/// @param eye Position of the camera
 	/// @param center Position where the camera is looking at
 	/// @param up Normalized up vector, how the camera is oriented. Typically (0, 0, 1)
 	/// @see gtc_matrix_transform
 	/// @see - frustum(T const & left, T const & right, T const & bottom, T const & top, T const & nearVal, T const & farVal) frustum(T const & left, T const & right, T const & bottom, T const & top, T const & nearVal, T const & farVal)
-	template <typename T> 
-	detail::tmat4x4<T> lookAt(
-		detail::tvec3<T> const & eye, 
-		detail::tvec3<T> const & center, 
-		detail::tvec3<T> const & up);
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> lookAt(
+		detail::tvec3<T, P> const & eye,
+		detail::tvec3<T, P> const & center,
+		detail::tvec3<T, P> const & up);
 
 	/// @}
 }//namespace glm

+ 122 - 120
glm/gtc/matrix_transform.inl

@@ -28,24 +28,24 @@
 
 namespace glm
 {
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> translate
 	(
-		detail::tmat4x4<T> const & m,
-		detail::tvec3<T> const & v
+		detail::tmat4x4<T, P> const & m,
+		detail::tvec3<T, P> const & v
 	)
 	{
-		detail::tmat4x4<T> Result(m);
+		detail::tmat4x4<T, P> Result(m);
 		Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
 		return Result;
 	}
 		
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> rotate
 	(
-		detail::tmat4x4<T> const & m,
-		T const & angle, 
-		detail::tvec3<T> const & v
+		detail::tmat4x4<T, P> const & m,
+		T const & angle,
+		detail::tvec3<T, P> const & v
 	)
 	{
 #ifdef GLM_FORCE_RADIANS
@@ -56,11 +56,11 @@ namespace glm
 		T c = cos(a);
 		T s = sin(a);
 
-		detail::tvec3<T> axis = normalize(v);
+		detail::tvec3<T, P> axis = normalize(v);
 
-		detail::tvec3<T> temp = (T(1) - c) * axis;
+		detail::tvec3<T, P> temp = (T(1) - c) * axis;
 
-		detail::tmat4x4<T> Rotate(detail::tmat4x4<T>::null);
+		detail::tmat4x4<T, P> Rotate(detail::tmat4x4<T, P>::null);
 		Rotate[0][0] = c + temp[0] * axis[0];
 		Rotate[0][1] = 0 + temp[0] * axis[1] + s * axis[2];
 		Rotate[0][2] = 0 + temp[0] * axis[2] - s * axis[1];
@@ -73,7 +73,7 @@ namespace glm
 		Rotate[2][1] = 0 + temp[2] * axis[1] - s * axis[0];
 		Rotate[2][2] = c + temp[2] * axis[2];
 
-		detail::tmat4x4<T> Result(detail::tmat4x4<T>::null);
+		detail::tmat4x4<T, P> Result(detail::tmat4x4<T, P>::null);
 		Result[0] = m[0] * Rotate[0][0] + m[1] * Rotate[0][1] + m[2] * Rotate[0][2];
 		Result[1] = m[0] * Rotate[1][0] + m[1] * Rotate[1][1] + m[2] * Rotate[1][2];
 		Result[2] = m[0] * Rotate[2][0] + m[1] * Rotate[2][1] + m[2] * Rotate[2][2];
@@ -81,14 +81,14 @@ namespace glm
 		return Result;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> scale
 	(
-		detail::tmat4x4<T> const & m,
-		detail::tvec3<T> const & v
+		detail::tmat4x4<T, P> const & m,
+		detail::tvec3<T, P> const & v
 	)
 	{
-		detail::tmat4x4<T> Result(detail::tmat4x4<T>::null);
+		detail::tmat4x4<T, P> Result(detail::tmat4x4<T, P>::null);
 		Result[0] = m[0] * v[0];
 		Result[1] = m[1] * v[1];
 		Result[2] = m[2] * v[2];
@@ -96,15 +96,15 @@ namespace glm
 		return Result;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> translate_slow
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> translate_slow
 	(
-		detail::tmat4x4<T> const & m,
-		detail::tvec3<T> const & v
+		detail::tmat4x4<T, P> const & m,
+		detail::tvec3<T, P> const & v
 	)
 	{
-		detail::tmat4x4<T> Result(T(1));
-		Result[3] = detail::tvec4<T>(v, T(1));
+		detail::tmat4x4<T, P> Result(T(1));
+		Result[3] = detail::tvec4<T, P>(v, T(1));
 		return m * Result;
 
 		//detail::tmat4x4<valType> Result(m);
@@ -116,12 +116,12 @@ namespace glm
 		//return Result;
 	}
 		
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> rotate_slow
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> rotate_slow
 	(
-		detail::tmat4x4<T> const & m,
+		detail::tmat4x4<T, P> const & m,
 		T const & angle, 
-		detail::tvec3<T> const & v
+		detail::tvec3<T, P> const & v
 	)
 	{
 #ifdef GLM_FORCE_RADIANS
@@ -131,9 +131,9 @@ namespace glm
 #endif
 		T c = cos(a);
 		T s = sin(a);
-		detail::tmat4x4<T> Result;
+		detail::tmat4x4<T, P> Result;
 
-		detail::tvec3<T> axis = normalize(v);
+		detail::tvec3<T, P> axis = normalize(v);
 
 		Result[0][0] = c + (1 - c)      * axis.x     * axis.x;
 		Result[0][1] = (1 - c) * axis.x * axis.y + s * axis.z;
@@ -150,73 +150,75 @@ namespace glm
 		Result[2][2] = c + (1 - c) * axis.z * axis.z;
 		Result[2][3] = 0;
 
-		Result[3] = detail::tvec4<T>(0, 0, 0, 1);
+		Result[3] = detail::tvec4<T, P>(0, 0, 0, 1);
 		return m * Result;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> scale_slow
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> scale_slow
 	(
-		detail::tmat4x4<T> const & m,
-		detail::tvec3<T> const & v
+		detail::tmat4x4<T, P> const & m,
+		detail::tvec3<T, P> const & v
 	)
 	{
-		detail::tmat4x4<T> Result(T(1));
+		detail::tmat4x4<T, P> Result(T(1));
 		Result[0][0] = v.x;
 		Result[1][1] = v.y;
 		Result[2][2] = v.z;
 		return m * Result;
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> ortho
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> ortho
 	(
-		valType const & left, 
-		valType const & right, 
-		valType const & bottom, 
-		valType const & top, 
-		valType const & zNear, 
-		valType const & zFar
+		T const & left,
+		T const & right,
+		T const & bottom,
+		T const & top,
+		T const & zNear,
+		T const & zFar
 	)
 	{
-		detail::tmat4x4<valType> Result(1);
-		Result[0][0] = valType(2) / (right - left);
-		Result[1][1] = valType(2) / (top - bottom);
-		Result[2][2] = - valType(2) / (zFar - zNear);
+		detail::tmat4x4<T, defaultp> Result(1);
+		Result[0][0] = T(2) / (right - left);
+		Result[1][1] = T(2) / (top - bottom);
+		Result[2][2] = - T(2) / (zFar - zNear);
 		Result[3][0] = - (right + left) / (right - left);
 		Result[3][1] = - (top + bottom) / (top - bottom);
 		Result[3][2] = - (zFar + zNear) / (zFar - zNear);
 		return Result;
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> ortho(
-		valType const & left, 
-		valType const & right, 
-		valType const & bottom, 
-		valType const & top)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> ortho
+	(
+		T const & left,
+		T const & right,
+		T const & bottom,
+		T const & top
+	)
 	{
-		detail::tmat4x4<valType> Result(1);
-		Result[0][0] = valType(2) / (right - left);
-		Result[1][1] = valType(2) / (top - bottom);
-		Result[2][2] = - valType(1);
+		detail::tmat4x4<T, defaultp> Result(1);
+		Result[0][0] = T(2) / (right - left);
+		Result[1][1] = T(2) / (top - bottom);
+		Result[2][2] = - T(1);
 		Result[3][0] = - (right + left) / (right - left);
 		Result[3][1] = - (top + bottom) / (top - bottom);
 		return Result;
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> frustum
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType, defaultp> frustum
 	(
-		valType const & left, 
-		valType const & right, 
-		valType const & bottom, 
-		valType const & top, 
-		valType const & nearVal, 
+		valType const & left,
+		valType const & right,
+		valType const & bottom,
+		valType const & top,
+		valType const & nearVal,
 		valType const & farVal
 	)
 	{
-		detail::tmat4x4<valType> Result(0);
+		detail::tmat4x4<valType, defaultp> Result(0);
 		Result[0][0] = (valType(2) * nearVal) / (right - left);
 		Result[1][1] = (valType(2) * nearVal) / (top - bottom);
 		Result[2][0] = (right + left) / (right - left);
@@ -227,12 +229,12 @@ namespace glm
 		return Result;
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> perspective
+	template <typename valType>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType, defaultp> perspective
 	(
-		valType const & fovy, 
-		valType const & aspect, 
-		valType const & zNear, 
+		valType const & fovy,
+		valType const & aspect,
+		valType const & zNear,
 		valType const & zFar
 	)
 	{
@@ -247,7 +249,7 @@ namespace glm
 		valType bottom = -range;
 		valType top = range;
 
-		detail::tmat4x4<valType> Result(valType(0));
+		detail::tmat4x4<valType, defaultp> Result(valType(0));
 		Result[0][0] = (valType(2) * zNear) / (right - left);
 		Result[1][1] = (valType(2) * zNear) / (top - bottom);
 		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
@@ -257,12 +259,12 @@ namespace glm
 	}
 	
 	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> perspectiveFov
+	GLM_FUNC_QUALIFIER detail::tmat4x4<valType, defaultp> perspectiveFov
 	(
-		valType const & fov, 
-		valType const & width, 
-		valType const & height, 
-		valType const & zNear, 
+		valType const & fov,
+		valType const & width,
+		valType const & height,
+		valType const & zNear,
 		valType const & zFar
 	)
 	{
@@ -274,7 +276,7 @@ namespace glm
 		valType h = glm::cos(valType(0.5) * rad) / glm::sin(valType(0.5) * rad);
 		valType w = h * height / width; ///todo max(width , Height) / min(width , Height)?
 
-		detail::tmat4x4<valType> Result(valType(0));
+		detail::tmat4x4<valType, defaultp> Result(valType(0));
 		Result[0][0] = w;
 		Result[1][1] = h;
 		Result[2][2] = - (zFar + zNear) / (zFar - zNear);
@@ -283,8 +285,8 @@ namespace glm
 		return Result;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> infinitePerspective
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> infinitePerspective
 	(
 		T fovy, 
 		T aspect, 
@@ -301,7 +303,7 @@ namespace glm
 		T bottom = -range;
 		T top = range;
 
-		detail::tmat4x4<T> Result(T(0));
+		detail::tmat4x4<T, defaultp> Result(T(0));
 		Result[0][0] = (T(2) * zNear) / (right - left);
 		Result[1][1] = (T(2) * zNear) / (top - bottom);
 		Result[2][2] = - T(1);
@@ -310,8 +312,8 @@ namespace glm
 		return Result;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> tweakedInfinitePerspective
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> tweakedInfinitePerspective
 	(
 		T fovy,
 		T aspect,
@@ -328,7 +330,7 @@ namespace glm
 		T bottom = -range;
 		T top = range;
 
-		detail::tmat4x4<T> Result(T(0));
+		detail::tmat4x4<T, defaultp> Result(T(0));
 		Result[0][0] = (T(2) * zNear) / (right - left);
 		Result[1][1] = (T(2) * zNear) / (top - bottom);
 		Result[2][2] = T(0.0001) - T(1);
@@ -337,16 +339,16 @@ namespace glm
 		return Result;
 	}
 
-	template <typename T, typename U>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> project
+	template <typename T, precision P, typename U>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> project
 	(
-		detail::tvec3<T> const & obj, 
-		detail::tmat4x4<T> const & model, 
-		detail::tmat4x4<T> const & proj, 
-		detail::tvec4<U> const & viewport
+		detail::tvec3<T, P> const & obj,
+		detail::tmat4x4<T, P> const & model,
+		detail::tmat4x4<T, P> const & proj,
+		detail::tvec4<U, P> const & viewport
 	)
 	{
-		detail::tvec4<T> tmp = detail::tvec4<T>(obj, T(1));
+		detail::tvec4<T, P> tmp = detail::tvec4<T, P>(obj, T(1));
 		tmp = model * tmp;
 		tmp = proj * tmp;
 
@@ -355,69 +357,69 @@ namespace glm
 		tmp[0] = tmp[0] * T(viewport[2]) + T(viewport[0]);
 		tmp[1] = tmp[1] * T(viewport[3]) + T(viewport[1]);
 
-		return detail::tvec3<T>(tmp);
+		return detail::tvec3<T, P>(tmp);
 	}
 
-	template <typename T, typename U>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> unProject
+	template <typename T, precision P, typename U>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> unProject
 	(
-		detail::tvec3<T> const & win, 
-		detail::tmat4x4<T> const & model, 
-		detail::tmat4x4<T> const & proj, 
-		detail::tvec4<U> const & viewport
+		detail::tvec3<T, P> const & win,
+		detail::tmat4x4<T, P> const & model,
+		detail::tmat4x4<T, P> const & proj,
+		detail::tvec4<U, P> const & viewport
 	)
 	{
-		detail::tmat4x4<T> inverse = glm::inverse(proj * model);
+		detail::tmat4x4<T, P> inverse = glm::inverse(proj * model);
 
-		detail::tvec4<T> tmp = detail::tvec4<T>(win, T(1));
+		detail::tvec4<T, P> tmp = detail::tvec4<T, P>(win, T(1));
 		tmp.x = (tmp.x - T(viewport[0])) / T(viewport[2]);
 		tmp.y = (tmp.y - T(viewport[1])) / T(viewport[3]);
 		tmp = tmp * T(2) - T(1);
 
-		detail::tvec4<T> obj = inverse * tmp;
+		detail::tvec4<T, P> obj = inverse * tmp;
 		obj /= obj.w;
 
-		return detail::tvec3<T>(obj);
+		return detail::tvec3<T, P>(obj);
 	}
 
-	template <typename T, typename U> 
-	detail::tmat4x4<T> pickMatrix
+	template <typename T, precision P, typename U>
+	detail::tmat4x4<T, P> pickMatrix
 	(
-		detail::tvec2<T> const & center,
-		detail::tvec2<T> const & delta,
-		detail::tvec4<U> const & viewport
+		detail::tvec2<T, P> const & center,
+		detail::tvec2<T, P> const & delta,
+		detail::tvec4<U, P> const & viewport
 	)
 	{
 		assert(delta.x > T(0) && delta.y > T(0));
-		detail::tmat4x4<T> Result(1.0f);
+		detail::tmat4x4<T, P> Result(1.0f);
 
 		if(!(delta.x > T(0) && delta.y > T(0)))
 			return Result; // Error
 
-		detail::tvec3<T> Temp(
+		detail::tvec3<T, P> Temp(
 			(T(viewport[2]) - T(2) * (center.x - T(viewport[0]))) / delta.x,
 			(T(viewport[3]) - T(2) * (center.y - T(viewport[1]))) / delta.y,
 			T(0));
 
 		// Translate and scale the picked region to the entire window
 		Result = translate(Result, Temp);
-		return scale(Result, detail::tvec3<T>(T(viewport[2]) / delta.x, T(viewport[3]) / delta.y, T(1)));
+		return scale(Result, detail::tvec3<T, P>(T(viewport[2]) / delta.x, T(viewport[3]) / delta.y, T(1)));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> lookAt
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> lookAt
 	(
-		detail::tvec3<T> const & eye,
-		detail::tvec3<T> const & center,
-		detail::tvec3<T> const & up
+		detail::tvec3<T, P> const & eye,
+		detail::tvec3<T, P> const & center,
+		detail::tvec3<T, P> const & up
 	)
 	{
-		detail::tvec3<T> f = normalize(center - eye);
-		detail::tvec3<T> u = normalize(up);
-		detail::tvec3<T> s = normalize(cross(f, u));
+		detail::tvec3<T, P> f = normalize(center - eye);
+		detail::tvec3<T, P> u = normalize(up);
+		detail::tvec3<T, P> s = normalize(cross(f, u));
 		u = cross(s, f);
 
-		detail::tmat4x4<T> Result(1);
+		detail::tmat4x4<T, P> Result(1);
 		Result[0][0] = s.x;
 		Result[1][0] = s.y;
 		Result[2][0] = s.z;

文件差异内容过多而无法显示
+ 429 - 374
glm/gtc/noise.inl


+ 142 - 146
glm/gtc/quaternion.hpp

@@ -52,7 +52,7 @@
 namespace glm{
 namespace detail
 {
-	template <typename T> 
+	template <typename T, precision P>
 	struct tquat// : public genType<T, tquat>
 	{
 		enum ctor{null};
@@ -68,108 +68,108 @@ namespace detail
 		// Constructors
 		tquat();
 		explicit tquat(
-			value_type const & s, 
-			glm::detail::tvec3<T> const & v);
+			value_type const & s,
+			glm::detail::tvec3<T, P> const & v);
 		explicit tquat(
-			value_type const & w, 
-			value_type const & x, 
-			value_type const & y, 
+			value_type const & w,
+			value_type const & x,
+			value_type const & y,
 			value_type const & z);
 
 		// Convertions
 
 		/// Build a quaternion from euler angles (pitch, yaw, roll), in radians.
 		explicit tquat(
-			tvec3<T> const & eulerAngles);
+			tvec3<T, P> const & eulerAngles);
 		explicit tquat(
-			tmat3x3<T> const & m);
+			tmat3x3<T, P> const & m);
 		explicit tquat(
-			tmat4x4<T> const & m);
+			tmat4x4<T, P> const & m);
 
 		// Accesses
 		value_type & operator[](int i);
 		value_type const & operator[](int i) const;
 
 		// Operators
-		tquat<T> & operator*=(value_type const & s);
-		tquat<T> & operator/=(value_type const & s);
+		tquat<T, P> & operator*=(value_type const & s);
+		tquat<T, P> & operator/=(value_type const & s);
 	};
 
-	template <typename T> 
-	detail::tquat<T> operator- (
-		detail::tquat<T> const & q);
-
-	template <typename T> 
-	detail::tquat<T> operator+ ( 
-		detail::tquat<T> const & q, 
-		detail::tquat<T> const & p); 
-
-	template <typename T> 
-	detail::tquat<T> operator* ( 
-		detail::tquat<T> const & q, 
-		detail::tquat<T> const & p); 
-
-	template <typename T> 
-	detail::tvec3<T> operator* (
-		detail::tquat<T> const & q, 
-		detail::tvec3<T> const & v);
-
-	template <typename T> 
-	detail::tvec3<T> operator* (
-		detail::tvec3<T> const & v,
-		detail::tquat<T> const & q);
-
-	template <typename T> 
-	detail::tvec4<T> operator* (
-		detail::tquat<T> const & q, 
-		detail::tvec4<T> const & v);
-
-	template <typename T> 
-	detail::tvec4<T> operator* (
-		detail::tvec4<T> const & v,
-		detail::tquat<T> const & q);
-
-	template <typename T> 
-	detail::tquat<T> operator* (
-		detail::tquat<T> const & q, 
-		typename detail::tquat<T>::value_type const & s);
-
-	template <typename T> 
-	detail::tquat<T> operator* (
-		typename detail::tquat<T>::value_type const & s,
-		detail::tquat<T> const & q);
-
-	template <typename T> 
-	detail::tquat<T> operator/ (
-		detail::tquat<T> const & q, 
-		typename detail::tquat<T>::value_type const & s);
+	template <typename T, precision P>
+	detail::tquat<T, P> operator- (
+		detail::tquat<T, P> const & q);
+
+	template <typename T, precision P>
+	detail::tquat<T, P> operator+ (
+		detail::tquat<T, P> const & q,
+		detail::tquat<T, P> const & p);
+
+	template <typename T, precision P>
+	detail::tquat<T, P> operator* (
+		detail::tquat<T, P> const & q,
+		detail::tquat<T, P> const & p);
+
+	template <typename T, precision P>
+	detail::tvec3<T, P> operator* (
+		detail::tquat<T, P> const & q,
+		detail::tvec3<T, P> const & v);
+
+	template <typename T, precision P>
+	detail::tvec3<T, P> operator* (
+		detail::tvec3<T, P> const & v,
+		detail::tquat<T, P> const & q);
+
+	template <typename T, precision P>
+	detail::tvec4<T, P> operator* (
+		detail::tquat<T, P> const & q, 
+		detail::tvec4<T, P> const & v);
+
+	template <typename T, precision P>
+	detail::tvec4<T, P> operator* (
+		detail::tvec4<T, P> const & v,
+		detail::tquat<T, P> const & q);
+
+	template <typename T, precision P>
+	detail::tquat<T, P> operator* (
+		detail::tquat<T, P> const & q,
+		T const & s);
+
+	template <typename T, precision P>
+	detail::tquat<T, P> operator* (
+		T const & s,
+		detail::tquat<T, P> const & q);
+
+	template <typename T, precision P>
+	detail::tquat<T, P> operator/ (
+		detail::tquat<T, P> const & q,
+		T const & s);
 
 } //namespace detail
 
 	/// @addtogroup gtc_quaternion
 	/// @{
 
-	/// Returns the length of the quaternion. 
+	/// Returns the length of the quaternion.
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
+	template <typename T, precision P>
 	T length(
-		detail::tquat<T> const & q);
+		detail::tquat<T, P> const & q);
 
-	/// Returns the normalized quaternion. 
+	/// Returns the normalized quaternion.
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tquat<T> normalize(
-		detail::tquat<T> const & q);
+	template <typename T, precision P>
+	detail::tquat<T, P> normalize(
+		detail::tquat<T, P> const & q);
 		
-	/// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ... 
+	/// Returns dot product of q1 and q2, i.e., q1[0] * q2[0] + q1[1] * q2[1] + ...
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
+	template <typename T, precision P>
 	T dot(
-		detail::tquat<T> const & q1, 
-		detail::tquat<T> const & q2);
+		detail::tquat<T, P> const & q1,
+		detail::tquat<T, P> const & q2);
 
 	/// Spherical linear interpolation of two quaternions.
 	/// The interpolation is oriented and the rotation is performed at constant speed.
@@ -180,14 +180,14 @@ namespace detail
 	/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
 	/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
 	/// @see gtc_quaternion
-	/// @see - slerp(detail::tquat<T> const & x, detail::tquat<T> const & y, T const & a) 
-	template <typename T> 
-	detail::tquat<T> mix(
-		detail::tquat<T> const & x, 
-		detail::tquat<T> const & y, 
+	/// @see - slerp(detail::tquat<T, P> const & x, detail::tquat<T, P> const & y, T const & a)
+	template <typename T, precision P>
+	detail::tquat<T, P> mix(
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y,
 		T const & a);
 
-	/// Linear interpolation of two quaternions. 
+	/// Linear interpolation of two quaternions.
 	/// The interpolation is oriented.
 	/// 
 	/// @param x A quaternion
@@ -195,10 +195,10 @@ namespace detail
 	/// @param a Interpolation factor. The interpolation is defined in the range [0, 1].
 	/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tquat<T> lerp(
-		detail::tquat<T> const & x, 
-		detail::tquat<T> const & y, 
+	template <typename T, precision P>
+	detail::tquat<T, P> lerp(
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y,
 		T const & a);
 
 	/// Spherical linear interpolation of two quaternions.
@@ -209,25 +209,25 @@ namespace detail
 	/// @param a Interpolation factor. The interpolation is defined beyond the range [0, 1].
 	/// @tparam T Value type used to build the quaternion. Supported: half, float or double.
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tquat<T> slerp(
-		detail::tquat<T> const & x, 
-		detail::tquat<T> const & y, 
+	template <typename T, precision P>
+	detail::tquat<T, P> slerp(
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y,
 		T const & a);
 
-	/// Returns the q conjugate. 
+	/// Returns the q conjugate.
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tquat<T> conjugate(
-		detail::tquat<T> const & q);
+	template <typename T, precision P>
+	detail::tquat<T, P> conjugate(
+		detail::tquat<T, P> const & q);
 
-	/// Returns the q inverse. 
+	/// Returns the q inverse.
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tquat<T> inverse(
-		detail::tquat<T> const & q);
+	template <typename T, precision P>
+	detail::tquat<T, P> inverse(
+		detail::tquat<T, P> const & q);
 
 	/// Rotates a quaternion from a vector of 3 components axis and an angle.
 	/// 
@@ -236,83 +236,79 @@ namespace detail
 	/// @param axis Axis of the rotation
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tquat<T> rotate(
-		detail::tquat<T> const & q, 
-		typename detail::tquat<T>::value_type const & angle, 
-		detail::tvec3<T> const & axis);
+	template <typename T, precision P>
+	detail::tquat<T, P> rotate(
+		detail::tquat<T, P> const & q,
+		T const & angle,
+		detail::tvec3<T, P> const & axis);
 
-	/// Returns euler angles, yitch as x, yaw as y, roll as z. 
+	/// Returns euler angles, yitch as x, yaw as y, roll as z.
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tvec3<T> eulerAngles(
-		detail::tquat<T> const & x);
+	template <typename T, precision P>
+	detail::tvec3<T, P> eulerAngles(
+		detail::tquat<T, P> const & x);
 
 	/// Returns roll value of euler angles expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
 	///
 	/// @see gtx_quaternion
-	template <typename valType> 
-	valType roll(
-		detail::tquat<valType> const & x);
+	template <typename T, precision P>
+	T roll(detail::tquat<T, P> const & x);
 
 	/// Returns pitch value of euler angles expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
 	///
 	/// @see gtx_quaternion
-	template <typename valType> 
-	valType pitch(
-		detail::tquat<valType> const & x);
+	template <typename T, precision P>
+	T pitch(detail::tquat<T, P> const & x);
 
 	/// Returns yaw value of euler angles expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
 	///
 	/// @see gtx_quaternion
-	template <typename valType> 
-	valType yaw(
-		detail::tquat<valType> const & x);
+	template <typename T, precision P>
+	T yaw(detail::tquat<T, P> const & x);
 
-	/// Converts a quaternion to a 3 * 3 matrix. 
+	/// Converts a quaternion to a 3 * 3 matrix.
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tmat3x3<T> mat3_cast(
-		detail::tquat<T> const & x);
+	template <typename T, precision P>
+	detail::tmat3x3<T, P> mat3_cast(
+		detail::tquat<T, P> const & x);
 
-	/// Converts a quaternion to a 4 * 4 matrix. 
+	/// Converts a quaternion to a 4 * 4 matrix.
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tmat4x4<T> mat4_cast(
-		detail::tquat<T> const & x);
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> mat4_cast(
+		detail::tquat<T, P> const & x);
 
-	/// Converts a 3 * 3 matrix to a quaternion. 
+	/// Converts a 3 * 3 matrix to a quaternion.
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tquat<T> quat_cast(
-		detail::tmat3x3<T> const & x);
+	template <typename T, precision P>
+	detail::tquat<T, P> quat_cast(
+		detail::tmat3x3<T, P> const & x);
 
-	/// Converts a 4 * 4 matrix to a quaternion. 
+	/// Converts a 4 * 4 matrix to a quaternion.
 	/// 
 	/// @see gtc_quaternion
-	template <typename T> 
-	detail::tquat<T> quat_cast(
-		detail::tmat4x4<T> const & x);
+	template <typename T, precision P>
+	detail::tquat<T, P> quat_cast(
+		detail::tmat4x4<T, P> const & x);
 
-	/// Returns the quaternion rotation angle. 
+	/// Returns the quaternion rotation angle.
 	///
 	/// @see gtc_quaternion
-	template <typename valType> 
-	valType angle(
-		detail::tquat<valType> const & x);
+	template <typename T, precision P>
+	T angle(detail::tquat<T, P> const & x);
 
-	/// Returns the q rotation axis. 
+	/// Returns the q rotation axis.
 	///
 	/// @see gtc_quaternion
-	template <typename valType> 
-	detail::tvec3<valType> axis(
-		detail::tquat<valType> const & x);
+	template <typename T, precision P>
+	detail::tvec3<T, P> axis(
+		detail::tquat<T, P> const & x);
 
-	/// Build a quaternion from an angle and a normalized axis. 
+	/// Build a quaternion from an angle and a normalized axis.
 	///
 	/// @param angle Angle expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
 	/// @param x x component of the x-axis, x, y, z must be a normalized axis
@@ -320,23 +316,23 @@ namespace detail
 	/// @param z z component of the z-axis, x, y, z must be a normalized axis
 	///
 	/// @see gtc_quaternion
-	template <typename valType> 
-	detail::tquat<valType> angleAxis(
-		valType const & angle, 
-		valType const & x, 
-		valType const & y, 
-		valType const & z);
+	template <typename T, precision P>
+	detail::tquat<T, P> angleAxis(
+		T const & angle,
+		T const & x,
+		T const & y,
+		T const & z);
 
 	/// Build a quaternion from an angle and a normalized axis.
 	///
 	/// @param angle Angle expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.
-	/// @param axis Axis of the quaternion, must be normalized. 
+	/// @param axis Axis of the quaternion, must be normalized.
 	///
 	/// @see gtc_quaternion
-	template <typename valType> 
-	detail::tquat<valType> angleAxis(
-		valType const & angle, 
-		detail::tvec3<valType> const & axis);
+	template <typename T, precision P>
+	detail::tquat<T, P> angleAxis(
+		T const & angle,
+		detail::tvec3<T, P> const & axis);
 
 	/// @}
 } //namespace glm

+ 244 - 244
glm/gtc/quaternion.inl

@@ -31,39 +31,39 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tquat<T>::size_type tquat<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tquat<T, P>::size_type tquat<T, P>::length() const
 	{
 		return 4;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tquat<T>::tquat() : 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tquat<T, P>::tquat() :
 		x(0),
 		y(0),
 		z(0),
 		w(1)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tquat<T>::tquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tquat<T, P>::tquat
 	(
-		value_type const & s, 
-		tvec3<T> const & v
-	) : 
+		T const & s,
+		tvec3<T, P> const & v
+	) :
 		x(v.x),
 		y(v.y),
 		z(v.z),
 		w(s)
 	{}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tquat<T>::tquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tquat<T, P>::tquat
 	(
-		value_type const & w, 
-		value_type const & x, 
-		value_type const & y, 
-		value_type const & z
+		T const & w,
+		T const & x,
+		T const & y,
+		T const & z
 	) :
 		x(x),
 		y(y),
@@ -77,8 +77,8 @@ namespace detail
 	//template <typename valType> 
 	//GLM_FUNC_QUALIFIER tquat<valType>::tquat
 	//(
-	//	valType const & pitch, 
-	//	valType const & yaw, 
+	//	valType const & pitch,
+	//	valType const & yaw,
 	//	valType const & roll
 	//)
 	//{
@@ -92,14 +92,14 @@ namespace detail
 	//	this->z = c.x * c.y * s.z - s.x * s.y * c.z;
 	//}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tquat<T>::tquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tquat<T, P>::tquat
 	(
-		tvec3<T> const & eulerAngle
+		tvec3<T, P> const & eulerAngle
 	)
 	{
-		tvec3<T> c = glm::cos(eulerAngle * value_type(0.5));
-		tvec3<T> s = glm::sin(eulerAngle * value_type(0.5));
+		tvec3<T, P> c = glm::cos(eulerAngle * value_type(0.5));
+		tvec3<T, P> s = glm::sin(eulerAngle * value_type(0.5));
 		
 		this->w = c.x * c.y * c.z + s.x * s.y * s.z;
 		this->x = s.x * c.y * c.z - c.x * s.y * s.z;
@@ -107,35 +107,35 @@ namespace detail
 		this->z = c.x * c.y * s.z - s.x * s.y * c.z;		
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tquat<T>::tquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tquat<T, P>::tquat
 	(
-		tmat3x3<T> const & m
+		tmat3x3<T, P> const & m
 	)
 	{
 		*this = quat_cast(m);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tquat<T>::tquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tquat<T, P>::tquat
 	(
-		tmat4x4<T> const & m
+		tmat4x4<T, P> const & m
 	)
 	{
 		*this = quat_cast(m);
 	}
 
 	//////////////////////////////////////////////////////////////
-	// tquat<T> accesses
+	// tquat<T, P> accesses
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tquat<T>::value_type & tquat<T>::operator [] (int i)
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER T & tquat<T, P>::operator [](int i)
 	{
 		return (&x)[i];
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER typename tquat<T>::value_type const & tquat<T>::operator [] (int i) const
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER T const & tquat<T, P>::operator [](int i) const
 	{
 		return (&x)[i];
 	}
@@ -143,10 +143,10 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// tquat<valType> operators
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tquat<T> & tquat<T>::operator *=
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tquat<T, P> & tquat<T, P>::operator *=
 	(
-		value_type const & s
+		T const & s
 	)
 	{
 		this->w *= s;
@@ -156,10 +156,10 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER tquat<T> & tquat<T>::operator /=
+	template <typename T, precision P> 
+	GLM_FUNC_QUALIFIER tquat<T, P> & tquat<T, P>::operator /=
 	(
-		value_type const & s
+		T const & s
 	)
 	{
 		this->w /= s;
@@ -172,143 +172,143 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// tquat<valType> external operators
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tquat<T> operator- 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> operator-
 	(
-		detail::tquat<T> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
-		return detail::tquat<T>(-q.w, -q.x, -q.y, -q.z);
+		return detail::tquat<T, P>(-q.w, -q.x, -q.y, -q.z);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> operator+
-	( 
-		detail::tquat<T> const & q, 
-		detail::tquat<T> const & p
-	) 
-	{ 
-		return detail::tquat<T>(
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> operator+
+	(
+		detail::tquat<T, P> const & q,
+		detail::tquat<T, P> const & p
+	)
+	{
+		return detail::tquat<T, P>(
 			q.w + p.w,
 			q.x + p.x,
 			q.y + p.y,
 			q.z + p.z);
-	} 
-
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> operator*
-	( 
-		detail::tquat<T> const & q, 
-		detail::tquat<T> const & p
-	) 
-	{ 
-		return detail::tquat<T>(
+	}
+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> operator*
+	(
+		detail::tquat<T, P> const & q,
+		detail::tquat<T, P> const & p
+	)
+	{
+		return detail::tquat<T, P>(
 			q.w * p.w - q.x * p.x - q.y * p.y - q.z * p.z,
 			q.w * p.x + q.x * p.w + q.y * p.z - q.z * p.y,
 			q.w * p.y + q.y * p.w + q.z * p.x - q.x * p.z,
 			q.w * p.z + q.z * p.w + q.x * p.y - q.y * p.x);
-	} 
+	}
 
 	// Transformation
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> operator*
 	(
-		detail::tquat<T> const & q, 
-		detail::tvec3<T> const & v
+		detail::tquat<T, P> const & q,
+		detail::tvec3<T, P> const & v
 	)
 	{
-		typename detail::tquat<T>::value_type Two(2);
+		typename detail::tquat<T, P>::value_type Two(2);
 
-		detail::tvec3<T> uv, uuv;
-		detail::tvec3<T> QuatVector(q.x, q.y, q.z);
+		detail::tvec3<T, P> uv, uuv;
+		detail::tvec3<T, P> QuatVector(q.x, q.y, q.z);
 		uv = glm::cross(QuatVector, v);
 		uuv = glm::cross(QuatVector, uv);
-		uv *= (Two * q.w); 
-		uuv *= Two; 
+		uv *= (Two * q.w);
+		uuv *= Two;
 
 		return v + uv + uuv;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> operator*
 	(
-		detail::tvec3<T> const & v,
-		detail::tquat<T> const & q 
+		detail::tvec3<T, P> const & v,
+		detail::tquat<T, P> const & q
 	)
 	{
 		return inverse(q) * v;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> operator*
 	(
-		detail::tquat<T> const & q, 
-		detail::tvec4<T> const & v
+		detail::tquat<T, P> const & q,
+		detail::tvec4<T, P> const & v
 	)
 	{
-		return detail::tvec4<T>(q * detail::tvec3<T>(v), v.w);
+		return detail::tvec4<T, P>(q * detail::tvec3<T, P>(v), v.w);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> operator*
 	(
-		detail::tvec4<T> const & v,
-		detail::tquat<T> const & q 
+		detail::tvec4<T, P> const & v,
+		detail::tquat<T, P> const & q
 	)
 	{
 		return inverse(q) * v;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> operator*
 	(
-		detail::tquat<T> const & q, 
-		typename detail::tquat<T>::value_type const & s
+		detail::tquat<T, P> const & q,
+		T const & s
 	)
 	{
-		return detail::tquat<T>(
+		return detail::tquat<T, P>(
 			q.w * s, q.x * s, q.y * s, q.z * s);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> operator* 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> operator*
 	(
-		typename detail::tquat<T>::value_type const & s,
-		detail::tquat<T> const & q
+		T const & s,
+		detail::tquat<T, P> const & q
 	)
 	{
 		return q * s;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> operator/ 
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> operator/
 	(
-		detail::tquat<T> const & q, 
-		typename detail::tquat<T>::value_type const & s
+		detail::tquat<T, P> const & q,
+		T const & s
 	)
 	{
-		return detail::tquat<T>(
+		return detail::tquat<T, P>(
 			q.w / s, q.x / s, q.y / s, q.z / s);
 	}
 
 	//////////////////////////////////////
 	// Boolean operators
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		detail::tquat<T> const & q1, 
-		detail::tquat<T> const & q2
+		detail::tquat<T, P> const & q1,
+		detail::tquat<T, P> const & q2
 	)
 	{
 		return (q1.x == q2.x) && (q1.y == q2.y) && (q1.z == q2.z) && (q1.w == q2.w);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		detail::tquat<T> const & q1, 
-		detail::tquat<T> const & q2
+		detail::tquat<T, P> const & q1,
+		detail::tquat<T, P> const & q2
 	)
 	{
 		return (q1.x != q2.x) || (q1.y != q2.y) || (q1.z != q2.z) || (q1.w != q2.w);
@@ -317,46 +317,46 @@ namespace detail
 }//namespace detail
 
 	////////////////////////////////////////////////////////
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T length
 	(
-		detail::tquat<T> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
 		return glm::sqrt(dot(q, q));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> normalize
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> normalize
 	(
-		detail::tquat<T> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
-		typename detail::tquat<T>::value_type len = length(q);
-		if(len <= typename detail::tquat<T>::value_type(0)) // Problem
-			return detail::tquat<T>(1, 0, 0, 0);
-		typename detail::tquat<T>::value_type oneOverLen = typename detail::tquat<T>::value_type(1) / len;
-		return detail::tquat<T>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
+		typename detail::tquat<T, P>::value_type len = length(q);
+		if(len <= typename detail::tquat<T, P>::value_type(0)) // Problem
+			return detail::tquat<T, P>(1, 0, 0, 0);
+		typename detail::tquat<T, P>::value_type oneOverLen = typename detail::tquat<T, P>::value_type(1) / len;
+		return detail::tquat<T, P>(q.w * oneOverLen, q.x * oneOverLen, q.y * oneOverLen, q.z * oneOverLen);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T dot
 	(
-		detail::tquat<T> const & q1, 
-		detail::tquat<T> const & q2
+		detail::tquat<T, P> const & q1,
+		detail::tquat<T, P> const & q2
 	)
 	{
 		return q1.x * q2.x + q1.y * q2.y + q1.z * q2.z + q1.w * q2.w;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> cross
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> cross
 	(
-		detail::tquat<T> const & q1, 
-		detail::tquat<T> const & q2
+		detail::tquat<T, P> const & q1,
+		detail::tquat<T, P> const & q2
 	)
 	{
-		return detail::tquat<T>(
+		return detail::tquat<T, P>(
 			q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z,
 			q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
 			q1.w * q2.y + q1.y * q2.w + q1.z * q2.x - q1.x * q2.z,
@@ -364,20 +364,20 @@ namespace detail
 	}
 /*
 	// (x * sin(1 - a) * angle / sin(angle)) + (y * sin(a) * angle / sin(angle))
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tquat<T> mix
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> mix
 	(
-		detail::tquat<T> const & x, 
-		detail::tquat<T> const & y, 
-		typename detail::tquat<T>::value_type const & a
+		detail::tquat<T, P> const & x, 
+		detail::tquat<T, P> const & y, 
+		typename detail::tquat<T, P>::value_type const & a
 	)
 	{
-		if(a <= typename detail::tquat<T>::value_type(0)) return x;
-		if(a >= typename detail::tquat<T>::value_type(1)) return y;
+		if(a <= typename detail::tquat<T, P>::value_type(0)) return x;
+		if(a >= typename detail::tquat<T, P>::value_type(1)) return y;
 
 		float fCos = dot(x, y);
-		detail::tquat<T> y2(y); //BUG!!! tquat<T> y2;
-		if(fCos < typename detail::tquat<T>::value_type(0))
+		detail::tquat<T, P> y2(y); //BUG!!! tquat<T, P> y2;
+		if(fCos < typename detail::tquat<T, P>::value_type(0))
 		{
 			y2 = -y;
 			fCos = -fCos;
@@ -385,32 +385,32 @@ namespace detail
 
 		//if(fCos > 1.0f) // problem
 		float k0, k1;
-		if(fCos > typename detail::tquat<T>::value_type(0.9999))
+		if(fCos > typename detail::tquat<T, P>::value_type(0.9999))
 		{
-			k0 = typename detail::tquat<T>::value_type(1) - a;
-			k1 = typename detail::tquat<T>::value_type(0) + a; //BUG!!! 1.0f + a;
+			k0 = typename detail::tquat<T, P>::value_type(1) - a;
+			k1 = typename detail::tquat<T, P>::value_type(0) + a; //BUG!!! 1.0f + a;
 		}
 		else
 		{
-			typename detail::tquat<T>::value_type fSin = sqrt(T(1) - fCos * fCos);
-			typename detail::tquat<T>::value_type fAngle = atan(fSin, fCos);
-			typename detail::tquat<T>::value_type fOneOverSin = T(1) / fSin;
-			k0 = sin((typename detail::tquat<T>::value_type(1) - a) * fAngle) * fOneOverSin;
-			k1 = sin((typename detail::tquat<T>::value_type(0) + a) * fAngle) * fOneOverSin;
+			typename detail::tquat<T, P>::value_type fSin = sqrt(T(1) - fCos * fCos);
+			typename detail::tquat<T, P>::value_type fAngle = atan(fSin, fCos);
+			typename detail::tquat<T, P>::value_type fOneOverSin = T(1) / fSin;
+			k0 = sin((typename detail::tquat<T, P>::value_type(1) - a) * fAngle) * fOneOverSin;
+			k1 = sin((typename detail::tquat<T, P>::value_type(0) + a) * fAngle) * fOneOverSin;
 		}
 
-		return detail::tquat<T>(
+		return detail::tquat<T, P>(
 			k0 * x.w + k1 * y2.w,
 			k0 * x.x + k1 * y2.x,
 			k0 * x.y + k1 * y2.y,
 			k0 * x.z + k1 * y2.z);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tquat<T> mix2
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> mix2
 	(
-		detail::tquat<T> const & x, 
-		detail::tquat<T> const & y, 
+		detail::tquat<T, P> const & x, 
+		detail::tquat<T, P> const & y, 
 		T const & a
 	)
 	{
@@ -444,11 +444,11 @@ namespace detail
 	}
 */
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tquat<T> mix
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> mix
 	(
-		detail::tquat<T> const & x, 
-		detail::tquat<T> const & y, 
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y,
 		T const & a
 	)
 	{
@@ -458,7 +458,7 @@ namespace detail
 		if(cosTheta > T(1) - epsilon<T>())
 		{
 			// Linear interpolation
-			return detail::tquat<T>(
+			return detail::tquat<T, P>(
 				mix(x.w, y.w, a),
 				mix(x.x, y.x, a),
 				mix(x.y, y.y, a),
@@ -472,11 +472,11 @@ namespace detail
 		}
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tquat<T> lerp
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> lerp
 	(
-		detail::tquat<T> const & x, 
-		detail::tquat<T> const & y, 
+		detail::tquat<T, P> const & x, 
+		detail::tquat<T, P> const & y, 
 		T const & a
 	)
 	{
@@ -487,15 +487,15 @@ namespace detail
 		return x * (T(1) - a) + (y * a);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tquat<T> slerp
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> slerp
 	(
-		detail::tquat<T> const & x, 
-		detail::tquat<T> const & y, 
+		detail::tquat<T, P> const & x,
+		detail::tquat<T, P> const & y,
 		T const & a
 	)
 	{
-		detail::tquat<T> z = y;
+		detail::tquat<T, P> z = y;
 
 		T cosTheta = dot(x, y);
 
@@ -511,7 +511,7 @@ namespace detail
 		if(cosTheta > T(1) - epsilon<T>())
 		{
 			// Linear interpolation
-			return detail::tquat<T>(
+			return detail::tquat<T, P>(
 				mix(x.w, y.w, a),
 				mix(x.x, y.x, a),
 				mix(x.y, y.y, a),
@@ -525,36 +525,36 @@ namespace detail
 		}
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> conjugate
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> conjugate
 	(
-		detail::tquat<T> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
-		return detail::tquat<T>(q.w, -q.x, -q.y, -q.z);
+		return detail::tquat<T, P>(q.w, -q.x, -q.y, -q.z);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> inverse
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> inverse
 	(
-		detail::tquat<T> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
 		return conjugate(q) / dot(q, q);
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> rotate
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> rotate
 	(
-		detail::tquat<T> const & q, 
-		typename detail::tquat<T>::value_type const & angle, 
-		detail::tvec3<T> const & v
+		detail::tquat<T, P> const & q,
+		typename detail::tquat<T, P>::value_type const & angle,
+		detail::tvec3<T, P> const & v
 	)
 	{
-		detail::tvec3<T> Tmp = v;
+		detail::tvec3<T, P> Tmp = v;
 
 		// Axis of rotation must be normalised
-		typename detail::tquat<T>::value_type len = glm::length(Tmp);
+		typename detail::tquat<T, P>::value_type len = glm::length(Tmp);
 		if(abs(len - T(1)) > T(0.001))
 		{
 			T oneOverLen = T(1) / len;
@@ -564,71 +564,71 @@ namespace detail
 		}
 
 #ifdef GLM_FORCE_RADIANS
-		typename detail::tquat<T>::value_type const AngleRad(angle);
+		typename detail::tquat<T, P>::value_type const AngleRad(angle);
 #else
-		typename detail::tquat<T>::value_type const AngleRad = radians(angle);
+		typename detail::tquat<T, P>::value_type const AngleRad = radians(angle);
 #endif
-		typename detail::tquat<T>::value_type const Sin = sin(AngleRad * T(0.5));
+		typename detail::tquat<T, P>::value_type const Sin = sin(AngleRad * T(0.5));
 
-		return q * detail::tquat<T>(cos(AngleRad * T(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
-		//return gtc::quaternion::cross(q, detail::tquat<T>(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin));
+		return q * detail::tquat<T, P>(cos(AngleRad * T(0.5)), Tmp.x * Sin, Tmp.y * Sin, Tmp.z * Sin);
+		//return gtc::quaternion::cross(q, detail::tquat<T, P>(cos(AngleRad * T(0.5)), Tmp.x * fSin, Tmp.y * fSin, Tmp.z * fSin));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec3<T> eulerAngles
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> eulerAngles
 	(
-		detail::tquat<T> const & x
+		detail::tquat<T, P> const & x
 	)
 	{
-		return detail::tvec3<T>(pitch(x), yaw(x), roll(x));
+		return detail::tvec3<T, P>(pitch(x), yaw(x), roll(x));
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER valType roll
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T roll
 	(
-		detail::tquat<valType> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
 #ifdef GLM_FORCE_RADIANS
-		return valType(atan2(valType(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
+		return T(atan2(T(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
 #else
-		return glm::degrees(atan(valType(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
+		return glm::degrees(atan(T(2) * (q.x * q.y + q.w * q.z), q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z));
 #endif
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER valType pitch
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T pitch
 	(
-		detail::tquat<valType> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
 #ifdef GLM_FORCE_RADIANS
-		return valType(atan2(valType(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
+		return T(atan2(T(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
 #else
-		return glm::degrees(atan(valType(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
+		return glm::degrees(atan(T(2) * (q.y * q.z + q.w * q.x), q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z));
 #endif
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER valType yaw
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER T yaw
 	(
-		detail::tquat<valType> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
 #ifdef GLM_FORCE_RADIANS
-		return asin(valType(-2) * (q.x * q.z - q.w * q.y));
+		return asin(T(-2) * (q.x * q.z - q.w * q.y));
 #else
-		return glm::degrees(asin(valType(-2) * (q.x * q.z - q.w * q.y)));
+		return glm::degrees(asin(T(-2) * (q.x * q.z - q.w * q.y)));
 #endif
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> mat3_cast
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> mat3_cast
 	(
-		detail::tquat<T> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
-		detail::tmat3x3<T> Result(T(1));
+		detail::tmat3x3<T, P> Result(T(1));
 		Result[0][0] = 1 - 2 * q.y * q.y - 2 * q.z * q.z;
 		Result[0][1] = 2 * q.x * q.y + 2 * q.w * q.z;
 		Result[0][2] = 2 * q.x * q.z - 2 * q.w * q.y;
@@ -643,28 +643,28 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> mat4_cast
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> mat4_cast
 	(
-		detail::tquat<T> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
-		return detail::tmat4x4<T>(mat3_cast(q));
+		return detail::tmat4x4<T, P>(mat3_cast(q));
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> quat_cast
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> quat_cast
 	(
-		detail::tmat3x3<T> const & m
+		detail::tmat3x3<T, P> const & m
 	)
 	{
-		typename detail::tquat<T>::value_type fourXSquaredMinus1 = m[0][0] - m[1][1] - m[2][2];
-		typename detail::tquat<T>::value_type fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2];
-		typename detail::tquat<T>::value_type fourZSquaredMinus1 = m[2][2] - m[0][0] - m[1][1];
-		typename detail::tquat<T>::value_type fourWSquaredMinus1 = m[0][0] + m[1][1] + m[2][2];
+		typename detail::tquat<T, P>::value_type fourXSquaredMinus1 = m[0][0] - m[1][1] - m[2][2];
+		typename detail::tquat<T, P>::value_type fourYSquaredMinus1 = m[1][1] - m[0][0] - m[2][2];
+		typename detail::tquat<T, P>::value_type fourZSquaredMinus1 = m[2][2] - m[0][0] - m[1][1];
+		typename detail::tquat<T, P>::value_type fourWSquaredMinus1 = m[0][0] + m[1][1] + m[2][2];
 
 		int biggestIndex = 0;
-		typename detail::tquat<T>::value_type fourBiggestSquaredMinus1 = fourWSquaredMinus1;
+		typename detail::tquat<T, P>::value_type fourBiggestSquaredMinus1 = fourWSquaredMinus1;
 		if(fourXSquaredMinus1 > fourBiggestSquaredMinus1)
 		{
 			fourBiggestSquaredMinus1 = fourXSquaredMinus1;
@@ -681,14 +681,14 @@ namespace detail
 			biggestIndex = 3;
 		}
 
-		typename detail::tquat<T>::value_type biggestVal = sqrt(fourBiggestSquaredMinus1 + T(1)) * T(0.5);
-		typename detail::tquat<T>::value_type mult = T(0.25) / biggestVal;
+		typename detail::tquat<T, P>::value_type biggestVal = sqrt(fourBiggestSquaredMinus1 + T(1)) * T(0.5);
+		typename detail::tquat<T, P>::value_type mult = T(0.25) / biggestVal;
 
-		detail::tquat<T> Result;
+		detail::tquat<T, P> Result;
 		switch(biggestIndex)
 		{
 		case 0:
-			Result.w = biggestVal; 
+			Result.w = biggestVal;
 			Result.x = (m[1][2] - m[2][1]) * mult;
 			Result.y = (m[2][0] - m[0][2]) * mult;
 			Result.z = (m[0][1] - m[1][0]) * mult;
@@ -719,19 +719,19 @@ namespace detail
 		return Result;
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tquat<T> quat_cast
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> quat_cast
 	(
-		detail::tmat4x4<T> const & m4
+		detail::tmat4x4<T, P> const & m4
 	)
 	{
-		return quat_cast(detail::tmat3x3<T>(m4));
+		return quat_cast(detail::tmat3x3<T, P>(m4));
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T angle
 	(
-		detail::tquat<T> const & x
+		detail::tquat<T, P> const & x
 	)
 	{
 #ifdef GLM_FORCE_RADIANS
@@ -741,48 +741,48 @@ namespace detail
 #endif
 	}
 
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec3<T> axis
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> axis
 	(
-		detail::tquat<T> const & x
+		detail::tquat<T, P> const & x
 	)
 	{
 		T tmp1 = T(1) - x.w * x.w;
 		if(tmp1 <= T(0))
-			return detail::tvec3<T>(0, 0, 1);
+			return detail::tvec3<T, P>(0, 0, 1);
 		T tmp2 = T(1) / sqrt(tmp1);
-		return detail::tvec3<T>(x.x * tmp2, x.y * tmp2, x.z * tmp2);
+		return detail::tvec3<T, P>(x.x * tmp2, x.y * tmp2, x.z * tmp2);
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tquat<T, defaultp> angleAxis
 	(
-		valType const & angle, 
-		valType const & x, 
-		valType const & y, 
-		valType const & z
+		T const & angle,
+		T const & x,
+		T const & y,
+		T const & z
 	)
 	{
-		return angleAxis(angle, detail::tvec3<valType>(x, y, z));
+		return angleAxis(angle, detail::tvec3<T, defaultp>(x, y, z));
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tquat<valType> angleAxis
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tquat<T, P> angleAxis
 	(
-		valType const & angle, 
-		detail::tvec3<valType> const & v
+		T const & angle,
+		detail::tvec3<T, P> const & v
 	)
 	{
-		detail::tquat<valType> result;
+		detail::tquat<T, P> result;
 
 #ifdef GLM_FORCE_RADIANS
-		valType a(angle);
+		T const a(angle);
 #else
-		valType a(glm::radians(angle));
+		T const a(glm::radians(angle));
 #endif
-		valType s = glm::sin(a * valType(0.5));
+		T s = glm::sin(a * T(0.5));
 
-		result.w = glm::cos(a * valType(0.5));
+		result.w = glm::cos(a * T(0.5));
 		result.x = v.x * s;
 		result.y = v.y * s;
 		result.z = v.z * s;

+ 13 - 13
glm/gtc/random.hpp

@@ -59,9 +59,9 @@ namespace glm
 	/// @param Max 
 	/// @tparam genType Value type. Currently supported: half (not recommanded), float or double scalars and vectors.
 	/// @see gtc_random
-	template <typename genType> 
+	template <typename genType>
 	genType linearRand(
-		genType const & Min, 
+		genType const & Min,
 		genType const & Max);
 
 	/// Generate random numbers in the interval [Min, Max], according a gaussian distribution 
@@ -71,39 +71,39 @@ namespace glm
 	/// @see gtc_random
 	template <typename genType>
 	genType gaussRand(
-		genType const & Mean, 
+		genType const & Mean,
 		genType const & Deviation);
 	
 	/// Generate a random 2D vector which coordinates are regulary distributed on a circle of a given radius
 	/// 
 	/// @param Radius 
 	/// @see gtc_random
-	template <typename T> 
-	detail::tvec2<T> circularRand(
-		T const & Radius); 
+	template <typename T>
+	detail::tvec2<T, defaultp> circularRand(
+		T const & Radius);
 	
 	/// Generate a random 3D vector which coordinates are regulary distributed on a sphere of a given radius
 	/// 
 	/// @param Radius
 	/// @see gtc_random
-	template <typename T> 
-	detail::tvec3<T> sphericalRand(
-		T const & Radius); 
+	template <typename T>
+	detail::tvec3<T, defaultp> sphericalRand(
+		T const & Radius);
 	
 	/// Generate a random 2D vector which coordinates are regulary distributed within the area of a disk of a given radius
 	/// 
 	/// @param Radius
 	/// @see gtc_random
-	template <typename T> 
-	detail::tvec2<T> diskRand(
-		T const & Radius); 
+	template <typename T>
+	detail::tvec2<T, defaultp> diskRand(
+		T const & Radius);
 	
 	/// Generate a random 3D vector which coordinates are regulary distributed within the volume of a ball of a given radius
 	/// 
 	/// @param Radius
 	/// @see gtc_random
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> ballRand(
+	detail::tvec3<T, defaultp> ballRand(
 		T const & Radius);
 	
 	/// @}

+ 16 - 12
glm/gtc/random.inl

@@ -105,17 +105,19 @@ namespace detail
 	VECTORIZE_VEC_VEC(gaussRand)
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> diskRand
+	GLM_FUNC_QUALIFIER detail::tvec2<T, defaultp> diskRand
 	(
 		T const & Radius
 	)
 	{		
-		detail::tvec2<T> Result(T(0));
+		detail::tvec2<T, defaultp> Result(T(0));
 		T LenRadius(T(0));
 		
 		do
 		{
-			Result = linearRand(detail::tvec2<T>(-Radius), detail::tvec2<T>(Radius));
+			Result = linearRand(
+				detail::tvec2<T, defaultp>(-Radius),
+				detail::tvec2<T, defaultp>(Radius));
 			LenRadius = length(Result);
 		}
 		while(LenRadius > Radius);
@@ -124,17 +126,19 @@ namespace detail
 	}
 	
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> ballRand
+	GLM_FUNC_QUALIFIER detail::tvec3<T, defaultp> ballRand
 	(
 		T const & Radius
 	)
 	{		
-		detail::tvec3<T> Result(T(0));
+		detail::tvec3<T, defaultp> Result(T(0));
 		T LenRadius(T(0));
 		
 		do
 		{
-			Result = linearRand(detail::tvec3<T>(-Radius), detail::tvec3<T>(Radius));
+			Result = linearRand(
+				detail::tvec3<T, defaultp>(-Radius),
+				detail::tvec3<T, defaultp>(Radius));
 			LenRadius = length(Result);
 		}
 		while(LenRadius > Radius);
@@ -142,18 +146,18 @@ namespace detail
 		return Result;
 	}
 	
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec2<T> circularRand
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, defaultp> circularRand
 	(
 		T const & Radius
 	)
 	{
 		T a = linearRand(T(0), T(6.283185307179586476925286766559f));
-		return detail::tvec2<T>(cos(a), sin(a)) * Radius;		
+		return detail::tvec2<T, defaultp>(cos(a), sin(a)) * Radius;		
 	}
 	
-	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec3<T> sphericalRand
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, defaultp> sphericalRand
 	(
 		T const & Radius
 	)
@@ -166,6 +170,6 @@ namespace detail
 		T x = r * cos(a);
 		T y = r * sin(a);
 	
-		return detail::tvec3<T>(x, y, z) * Radius;	
+		return detail::tvec3<T, defaultp>(x, y, z) * Radius;	
 	}
 }//namespace glm

+ 54 - 48
glm/gtc/swizzle.hpp

@@ -51,54 +51,54 @@ namespace glm
 	/// @addtogroup gtc_swizzle
 	/// @{
 
-	template <typename T, template <typename> class vecType>
+	template <typename T, precision P, template <typename, precision> class vecType>
 	T const & swizzle(	
-		vecType<T> const & v,
+		vecType<T, P> const & v,
 		comp x);
 
-	template <typename T, template <typename> class vecType>
-	detail::tvec2<T> const & swizzle(
-		vecType<T> const & v,
+	template <typename T, precision P, template <typename, precision> class vecType>
+	detail::tvec2<T, P> const & swizzle(
+		vecType<T, P> const & v,
 		comp x, comp y);
 
-	template <typename T, template <typename> class vecType>
-	detail::tvec3<T> const & swizzle(
-		vecType<T> const & v,
+	template <typename T, precision P, template <typename, precision> class vecType>
+	detail::tvec3<T, P> const & swizzle(
+		vecType<T, P> const & v,
 		comp x, comp y, comp z);
 
-	template <typename T, template <typename> class vecType>
-	detail::tvec4<T> const & swizzle(
-		vecType<T> const & v,
+	template <typename T, precision P, template <typename, precision> class vecType>
+	detail::tvec4<T, P> const & swizzle(
+		vecType<T, P> const & v,
 		comp x, comp y, comp z, comp w);
 
-	template <typename T, template <typename> class vecType>
+	template <typename T, precision P, template <typename, precision> class vecType>
 	T & swizzle(
-		vecType<T> & v,
+		vecType<T, P> & v,
 		comp x);
 
-	template <typename T, template <typename> class vecType>
-	detail::tref2<T> swizzle(
-		vecType<T> & v,
+	template <typename T, precision P, template <typename, precision> class vecType>
+	detail::tref2<T, P> swizzle(
+		vecType<T, P> & v,
 		comp x, comp y);
 
-	template <typename T, template <typename> class vecType>
-	detail::tref3<T> swizzle(
-		vecType<T> & v,
+	template <typename T, precision P, template <typename, precision> class vecType>
+	detail::tref3<T, P> swizzle(
+		vecType<T, P> & v,
 		comp x, comp y, comp z);
 
-	template <typename T, template <typename> class vecType>
-	detail::tref4<T> swizzle(
-		vecType<T> & v,
+	template <typename T, precision P, template <typename, precision> class vecType>
+	detail::tref4<T, P> swizzle(
+		vecType<T, P> & v,
 		comp x, comp y, comp z, comp w);
 
-#	define static_swizzle1_const(TYPE, SIZE)							\
-		template <comp x>										\
-		GLM_FUNC_QUALIFIER TYPE swizzle(detail::tvec##SIZE<TYPE> const & v)	\
+#	define static_swizzle1_const(TYPE, SIZE)											\
+		template <comp x>																\
+		GLM_FUNC_QUALIFIER TYPE swizzle(detail::tvec##SIZE<TYPE, defaultp> const & v)	\
 		{return v[x];}											
 																
-#	define static_swizzle1_ref(TYPE, SIZE)									\
-		template <comp x>													\
-		GLM_FUNC_QUALIFIER TYPE& swizzle(detail::tvec##SIZE<TYPE> & v)		\
+#	define static_swizzle1_ref(TYPE, SIZE)												\
+		template <comp x>																\
+		GLM_FUNC_QUALIFIER TYPE& swizzle(detail::tvec##SIZE<TYPE, defaultp> & v)		\
 		{return v[x];}
 
 	static_swizzle1_ref(detail::float16, 2)
@@ -155,18 +155,21 @@ namespace glm
 
 #	define static_swizzle2_const(TYPE, SIZE)									\
 		template <comp x, comp y>												\
-		GLM_FUNC_QUALIFIER detail::tvec2<TYPE> swizzle(detail::tvec##SIZE<TYPE> const & v)	\
-		{return detail::tvec2<TYPE>(v[x], v[y]);}
+		GLM_FUNC_QUALIFIER detail::tvec2<TYPE, defaultp> swizzle(				\
+			detail::tvec##SIZE<TYPE, defaultp> const & v)						\
+		{return detail::tvec2<TYPE, defaultp>(v[x], v[y]);}
 
 #	define static_swizzle3_const(TYPE, SIZE)									\
 		template <comp x, comp y, comp z>										\
-		GLM_FUNC_QUALIFIER detail::tvec3<TYPE> swizzle(detail::tvec##SIZE<TYPE> const & v)	\
-		{return detail::tvec3<TYPE>(v[x], v[y], v[z]);}
+		GLM_FUNC_QUALIFIER detail::tvec3<TYPE, defaultp> swizzle(				\
+			detail::tvec##SIZE<TYPE, defaultp> const & v)						\
+		{return detail::tvec3<TYPE, defaultp>(v[x], v[y], v[z]);}
 
 #	define static_swizzle4_const(TYPE, SIZE)									\
 		template <comp x, comp y, comp z, comp w>								\
-		GLM_FUNC_QUALIFIER detail::tvec4<TYPE> swizzle(detail::tvec##SIZE<TYPE> const & v)	\
-		{return detail::tvec4<TYPE>(v[x], v[y], v[z], v[w]);}
+		GLM_FUNC_QUALIFIER detail::tvec4<TYPE, defaultp> swizzle(				\
+			detail::tvec##SIZE<TYPE, defaultp> const & v)						\
+		{return detail::tvec4<TYPE, defaultp>(v[x], v[y], v[z], v[w]);}
 
 
 	static_swizzle2_const(glm::f16, 2)
@@ -277,20 +280,23 @@ namespace glm
 	static_swizzle4_const(glm::u64, 3)
 	static_swizzle4_const(glm::u64, 4)
 
-#	define static_swizzle2_ref(TYPE, SIZE) \
-		template <glm::comp x, glm::comp y> \
-		GLM_FUNC_QUALIFIER glm::detail::tref2<TYPE> swizzle(detail::tvec##SIZE<TYPE> & v) \
-		{return glm::detail::tref2<TYPE>(v[x], v[y]);}	
-
-#	define static_swizzle3_ref(TYPE, SIZE) \
-		template <glm::comp x, glm::comp y, glm::comp z> \
-		GLM_FUNC_QUALIFIER glm::detail::tref3<TYPE> swizzle(detail::tvec##SIZE<TYPE> & v) \
-		{return glm::detail::tref3<TYPE>(v[x], v[y], v[z]);}	
-
-#	define static_swizzle4_ref(TYPE, SIZE) \
-		template <glm::comp x, glm::comp y, glm::comp z, glm::comp w> \
-		GLM_FUNC_QUALIFIER glm::detail::tref4<TYPE> swizzle(detail::tvec##SIZE<TYPE> & v) \
-		{return glm::detail::tref4<TYPE>(v[x], v[y], v[z], v[w]);}	
+#	define static_swizzle2_ref(TYPE, SIZE)									\
+		template <glm::comp x, glm::comp y>									\
+		GLM_FUNC_QUALIFIER glm::detail::tref2<TYPE, defaultp> swizzle(		\
+			detail::tvec##SIZE<TYPE, defaultp> & v)							\
+		{return glm::detail::tref2<TYPE, defaultp>(v[x], v[y]);}	
+
+#	define static_swizzle3_ref(TYPE, SIZE)									\
+		template <glm::comp x, glm::comp y, glm::comp z>					\
+		GLM_FUNC_QUALIFIER glm::detail::tref3<TYPE, defaultp> swizzle(		\
+			detail::tvec##SIZE<TYPE, defaultp> & v)							\
+		{return glm::detail::tref3<TYPE, defaultp>(v[x], v[y], v[z]);}	
+
+#	define static_swizzle4_ref(TYPE, SIZE)									\
+		template <glm::comp x, glm::comp y, glm::comp z, glm::comp w>		\
+		GLM_FUNC_QUALIFIER glm::detail::tref4<TYPE, defaultp> swizzle(		\
+			detail::tvec##SIZE<TYPE, defaultp> & v)							\
+		{return glm::detail::tref4<TYPE, defaultp>(v[x], v[y], v[z], v[w]);}	
 
 	static_swizzle2_ref(glm::f16, 2)
 	static_swizzle2_ref(glm::f16, 3)

+ 29 - 29
glm/gtc/swizzle.inl

@@ -28,89 +28,89 @@
 
 namespace glm
 {
-	template <typename T, template <typename> class vecType>
+	template <typename T, precision P, template <typename, precision> class vecType>
 	GLM_FUNC_QUALIFIER T swizzle
 	(
-		vecType<T> const & v,
+		vecType<T, P> const & v,
 		comp x
 	)
 	{
-		assert(int(x) < int(vecType<T>::value_size));
+		assert(int(x) < int(vecType<T, P>::value_size));
 		return v[x];
 	}
 
-	template <typename T, template <typename> class vecType>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> swizzle
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> swizzle
 	(
-		vecType<T> const & v,
+		vecType<T, P> const & v,
 		comp x, comp y
 	)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			v[x],
 			v[y]);
 	}
 
-	template <typename T, template <typename> class vecType>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> swizzle
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> swizzle
 	(
-		vecType<T> const & v,
+		vecType<T, P> const & v,
 		comp x, comp y, comp z
 	)
 	{
-		return detail::tvec3<T>(
+		return detail::tvec3<T, P>(
 			v[x],
 			v[y],
 			v[z]);
 	}
 
-	template <typename T, template <typename> class vecType>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> swizzle
+	template <typename T, precision P, template <typename, precision> class vecType>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> swizzle
 	(
-		vecType<T> const & v,
+		vecType<T, P> const & v,
 		comp x, comp y, comp z, comp w
 	)
 	{
-		return detail::tvec4<T>(v[x], v[y],	v[z], v[w]);
+		return detail::tvec4<T, P>(v[x], v[y], v[z], v[w]);
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T& swizzle
 	(
-		detail::tvec4<T> & v,
+		detail::tvec4<T, P> & v,
 		comp x
 	)
 	{
 		return v[x];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tref2<T> swizzle
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tref2<T, P> swizzle
 	(
-		detail::tvec4<T> & v,
+		detail::tvec4<T, P> & v,
 		comp x, comp y
 	)
 	{
-		return detail::tref2<T>(v[x], v[y]);
+		return detail::tref2<T, P>(v[x], v[y]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tref3<T> swizzle
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tref3<T, P> swizzle
 	(
-		detail::tvec4<T> & v,
+		detail::tvec4<T, P> & v,
 		comp x, comp y, comp z
 	)
 	{
-		return detail::tref3<T>(v[x], v[y],	v[z]);
+		return detail::tref3<T, P>(v[x], v[y], v[z]);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tref4<T> swizzle
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tref4<T, P> swizzle
 	(
-		detail::tvec4<T> & v,
+		detail::tvec4<T, P> & v,
 		comp x, comp y, comp z, comp w
 	)
 	{
-		return detail::tref4<T>(v[x], v[y],	v[z], v[w]);
+		return detail::tref4<T, P>(v[x], v[y], v[z], v[w]);
 	}
 }//namespace glm

+ 105 - 105
glm/gtc/type_precision.hpp

@@ -113,70 +113,70 @@ namespace glm
 
 	/// 8 bit signed integer scalar type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<i8> i8vec1;
+	typedef detail::tvec1<i8, defaultp> i8vec1;
 	
 	/// 8 bit signed integer vector of 2 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<i8> i8vec2;
+	typedef detail::tvec2<i8, defaultp> i8vec2;
 
 	/// 8 bit signed integer vector of 3 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<i8> i8vec3;
+	typedef detail::tvec3<i8, defaultp> i8vec3;
 
 	/// 8 bit signed integer vector of 4 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<i8> i8vec4;
+	typedef detail::tvec4<i8, defaultp> i8vec4;
 
 
 	/// 16 bit signed integer scalar type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<i16> i16vec1;
+	typedef detail::tvec1<i16, defaultp> i16vec1;
 	
 	/// 16 bit signed integer vector of 2 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<i16> i16vec2;
+	typedef detail::tvec2<i16, defaultp> i16vec2;
 
 	/// 16 bit signed integer vector of 3 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<i16> i16vec3;
+	typedef detail::tvec3<i16, defaultp> i16vec3;
 
 	/// 16 bit signed integer vector of 4 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<i16> i16vec4;
+	typedef detail::tvec4<i16, defaultp> i16vec4;
 
 
 	/// 32 bit signed integer scalar type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<i32> i32vec1;
+	typedef detail::tvec1<i32, defaultp> i32vec1;
 	
 	/// 32 bit signed integer vector of 2 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<i32> i32vec2;
+	typedef detail::tvec2<i32, defaultp> i32vec2;
 
 	/// 32 bit signed integer vector of 3 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<i32> i32vec3;
+	typedef detail::tvec3<i32, defaultp> i32vec3;
 
 	/// 32 bit signed integer vector of 4 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<i32> i32vec4;
+	typedef detail::tvec4<i32, defaultp> i32vec4;
 
 
 	/// 64 bit signed integer scalar type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<i64> i64vec1;
+	typedef detail::tvec1<i64, defaultp> i64vec1;
 	
 	/// 64 bit signed integer vector of 2 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<i64> i64vec2;
+	typedef detail::tvec2<i64, defaultp> i64vec2;
 
 	/// 64 bit signed integer vector of 3 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<i64> i64vec3;
+	typedef detail::tvec3<i64, defaultp> i64vec3;
 
 	/// 64 bit signed integer vector of 4 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<i64> i64vec4;
+	typedef detail::tvec4<i64, defaultp> i64vec4;
 
 
 	/////////////////////////////
@@ -235,70 +235,70 @@ namespace glm
 
 	/// 8 bit unsigned integer scalar type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<u8> u8vec1;
+	typedef detail::tvec1<u8, defaultp> u8vec1;
 	
 	/// 8 bit unsigned integer vector of 2 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<u8> u8vec2;
+	typedef detail::tvec2<u8, defaultp> u8vec2;
 
 	/// 8 bit unsigned integer vector of 3 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<u8> u8vec3;
+	typedef detail::tvec3<u8, defaultp> u8vec3;
 
 	/// 8 bit unsigned integer vector of 4 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<u8> u8vec4;
+	typedef detail::tvec4<u8, defaultp> u8vec4;
 
 
 	/// 16 bit unsigned integer scalar type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<u16> u16vec1;
+	typedef detail::tvec1<u16, defaultp> u16vec1;
 	
 	/// 16 bit unsigned integer vector of 2 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<u16> u16vec2;
+	typedef detail::tvec2<u16, defaultp> u16vec2;
 
 	/// 16 bit unsigned integer vector of 3 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<u16> u16vec3;
+	typedef detail::tvec3<u16, defaultp> u16vec3;
 
 	/// 16 bit unsigned integer vector of 4 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<u16> u16vec4;
+	typedef detail::tvec4<u16, defaultp> u16vec4;
 
 
 	/// 32 bit unsigned integer scalar type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<u32> u32vec1;
+	typedef detail::tvec1<u32, defaultp> u32vec1;
 	
 	/// 32 bit unsigned integer vector of 2 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<u32> u32vec2;
+	typedef detail::tvec2<u32, defaultp> u32vec2;
 
 	/// 32 bit unsigned integer vector of 3 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<u32> u32vec3;
+	typedef detail::tvec3<u32, defaultp> u32vec3;
 
 	/// 32 bit unsigned integer vector of 4 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<u32> u32vec4;
+	typedef detail::tvec4<u32, defaultp> u32vec4;
 
 
 	/// 64 bit unsigned integer scalar type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<u64> u64vec1;
+	typedef detail::tvec1<u64, defaultp> u64vec1;
 	
 	/// 64 bit unsigned integer vector of 2 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<u64> u64vec2;
+	typedef detail::tvec2<u64, defaultp> u64vec2;
 
 	/// 64 bit unsigned integer vector of 3 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<u64> u64vec3;
+	typedef detail::tvec3<u64, defaultp> u64vec3;
 
 	/// 64 bit unsigned integer vector of 4 components type. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<u64> u64vec4;
+	typedef detail::tvec4<u64, defaultp> u64vec4;
 
 
 	//////////////////////
@@ -345,70 +345,70 @@ namespace glm
 
 	/// Single-precision floating-point vector of 1 component. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<float> fvec1;
+	typedef detail::tvec1<float, defaultp> fvec1;
 
 	/// Single-precision floating-point vector of 2 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<float> fvec2;
+	typedef detail::tvec2<float, defaultp> fvec2;
 
 	/// Single-precision floating-point vector of 3 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<float> fvec3;
+	typedef detail::tvec3<float, defaultp> fvec3;
 
 	/// Single-precision floating-point vector of 4 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<float> fvec4;
+	typedef detail::tvec4<float, defaultp> fvec4;
 
 
 	/// Half-precision floating-point vector of 1 component. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<f16> f16vec1;
+	typedef detail::tvec1<f16, defaultp> f16vec1;
 
 	/// Half-precision floating-point vector of 2 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<f16> f16vec2;
+	typedef detail::tvec2<f16, defaultp> f16vec2;
 
 	/// Half-precision floating-point vector of 3 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<f16> f16vec3;
+	typedef detail::tvec3<f16, defaultp> f16vec3;
 
 	/// Half-precision floating-point vector of 4 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<f16> f16vec4;
+	typedef detail::tvec4<f16, defaultp> f16vec4;
 
 	
 	/// Single-precision floating-point vector of 1 component. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<f32> f32vec1;
+	typedef detail::tvec1<f32, defaultp> f32vec1;
 
 	/// Single-precision floating-point vector of 2 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<f32> f32vec2;
+	typedef detail::tvec2<f32, defaultp> f32vec2;
 
 	/// Single-precision floating-point vector of 3 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<f32> f32vec3;
+	typedef detail::tvec3<f32, defaultp> f32vec3;
 
 	/// Single-precision floating-point vector of 4 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<f32> f32vec4;
+	typedef detail::tvec4<f32, defaultp> f32vec4;
 
 
 	/// Double-precision floating-point vector of 1 component. 
 	/// @see gtc_type_precision
-	typedef detail::tvec1<f64> f64vec1;
+	typedef detail::tvec1<f64, defaultp> f64vec1;
 
 	/// Double-precision floating-point vector of 2 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec2<f64> f64vec2;
+	typedef detail::tvec2<f64, defaultp> f64vec2;
 
 	/// Double-precision floating-point vector of 3 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec3<f64> f64vec3;
+	typedef detail::tvec3<f64, defaultp> f64vec3;
 
 	/// Double-precision floating-point vector of 4 components. 
 	/// @see gtc_type_precision
-	typedef detail::tvec4<f64> f64vec4;
+	typedef detail::tvec4<f64, defaultp> f64vec4;
 
 
 	//////////////////////
@@ -420,15 +420,15 @@ namespace glm
 
 	/// Single-precision floating-point 2x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f32> fmat2;
+	typedef detail::tmat2x2<f32, defaultp> fmat2;
 
 	/// Single-precision floating-point 3x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f32> fmat3;
+	typedef detail::tmat3x3<f32, defaultp> fmat3;
 
 	/// Single-precision floating-point 4x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f32> fmat4;
+	typedef detail::tmat4x4<f32, defaultp> fmat4;
 
 
 	/// Single-precision floating-point 1x1 matrix. 
@@ -437,56 +437,56 @@ namespace glm
 
 	/// Single-precision floating-point 2x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f32> fmat2x2;
+	typedef detail::tmat2x2<f32, defaultp> fmat2x2;
 
 	/// Single-precision floating-point 2x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x3<f32> fmat2x3;
+	typedef detail::tmat2x3<f32, defaultp> fmat2x3;
 
 	/// Single-precision floating-point 2x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x4<f32> fmat2x4;
+	typedef detail::tmat2x4<f32, defaultp> fmat2x4;
 
 	/// Single-precision floating-point 3x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x2<f32> fmat3x2;
+	typedef detail::tmat3x2<f32, defaultp> fmat3x2;
 
 	/// Single-precision floating-point 3x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f32> fmat3x3;
+	typedef detail::tmat3x3<f32, defaultp> fmat3x3;
 
 	/// Single-precision floating-point 3x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x4<f32> fmat3x4;
+	typedef detail::tmat3x4<f32, defaultp> fmat3x4;
 
 	/// Single-precision floating-point 4x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x2<f32> fmat4x2;
+	typedef detail::tmat4x2<f32, defaultp> fmat4x2;
 
 	/// Single-precision floating-point 4x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x3<f32> fmat4x3;
+	typedef detail::tmat4x3<f32, defaultp> fmat4x3;
 
 	/// Single-precision floating-point 4x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f32> fmat4x4;
+	typedef detail::tmat4x4<f32, defaultp> fmat4x4;
 
 
 	/// Half-precision floating-point 1x1 matrix. 
 	/// @see gtc_type_precision
-	//typedef detail::tmat1x1<f16> f16mat1;
+	//typedef detail::tmat1x1<f16, defaultp> f16mat1;
 
 	/// Half-precision floating-point 2x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f16> f16mat2;
+	typedef detail::tmat2x2<f16, defaultp> f16mat2;
 
 	/// Half-precision floating-point 3x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f16> f16mat3;
+	typedef detail::tmat3x3<f16, defaultp> f16mat3;
 
 	/// Half-precision floating-point 4x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f16> f16mat4;
+	typedef detail::tmat4x4<f16, defaultp> f16mat4;
 
 
 	/// Half-precision floating-point 1x1 matrix. 
@@ -495,56 +495,56 @@ namespace glm
 
 	/// Half-precision floating-point 2x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f16> f16mat2x2;
+	typedef detail::tmat2x2<f16, defaultp> f16mat2x2;
 
 	/// Half-precision floating-point 2x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x3<f16> f16mat2x3;
+	typedef detail::tmat2x3<f16, defaultp> f16mat2x3;
 
 	/// Half-precision floating-point 2x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x4<f16> f16mat2x4;
+	typedef detail::tmat2x4<f16, defaultp> f16mat2x4;
 
 	/// Half-precision floating-point 3x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x2<f16> f16mat3x2;
+	typedef detail::tmat3x2<f16, defaultp> f16mat3x2;
 
 	/// Half-precision floating-point 3x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f16> f16mat3x3;
+	typedef detail::tmat3x3<f16, defaultp> f16mat3x3;
 
 	/// Half-precision floating-point 3x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x4<f16> f16mat3x4;
+	typedef detail::tmat3x4<f16, defaultp> f16mat3x4;
 
 	/// Half-precision floating-point 4x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x2<f16> f16mat4x2;
+	typedef detail::tmat4x2<f16, defaultp> f16mat4x2;
 
 	/// Half-precision floating-point 4x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x3<f16> f16mat4x3;
+	typedef detail::tmat4x3<f16, defaultp> f16mat4x3;
 
 	/// Half-precision floating-point 4x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f16> f16mat4x4;
+	typedef detail::tmat4x4<f16, defaultp> f16mat4x4;
 
 
 	/// Single-precision floating-point 1x1 matrix. 
 	/// @see gtc_type_precision
-	//typedef detail::tmat1x1<f32> f32mat1;
+	//typedef detail::tmat1x1<f32, defaultp> f32mat1;
 
 	/// Single-precision floating-point 2x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f32> f32mat2;
+	typedef detail::tmat2x2<f32, defaultp> f32mat2;
 
 	/// Single-precision floating-point 3x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f32> f32mat3;
+	typedef detail::tmat3x3<f32, defaultp> f32mat3;
 
 	/// Single-precision floating-point 4x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f32> f32mat4;
+	typedef detail::tmat4x4<f32, defaultp> f32mat4;
 
 
 	/// Single-precision floating-point 1x1 matrix. 
@@ -553,56 +553,56 @@ namespace glm
 
 	/// Single-precision floating-point 2x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f32> f32mat2x2;
+	typedef detail::tmat2x2<f32, defaultp> f32mat2x2;
 
 	/// Single-precision floating-point 2x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x3<f32> f32mat2x3;
+	typedef detail::tmat2x3<f32, defaultp> f32mat2x3;
 
 	/// Single-precision floating-point 2x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x4<f32> f32mat2x4;
+	typedef detail::tmat2x4<f32, defaultp> f32mat2x4;
 
 	/// Single-precision floating-point 3x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x2<f32> f32mat3x2;
+	typedef detail::tmat3x2<f32, defaultp> f32mat3x2;
 
 	/// Single-precision floating-point 3x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f32> f32mat3x3;
+	typedef detail::tmat3x3<f32, defaultp> f32mat3x3;
 
 	/// Single-precision floating-point 3x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x4<f32> f32mat3x4;
+	typedef detail::tmat3x4<f32, defaultp> f32mat3x4;
 
 	/// Single-precision floating-point 4x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x2<f32> f32mat4x2;
+	typedef detail::tmat4x2<f32, defaultp> f32mat4x2;
 
 	/// Single-precision floating-point 4x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x3<f32> f32mat4x3;
+	typedef detail::tmat4x3<f32, defaultp> f32mat4x3;
 
 	/// Single-precision floating-point 4x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f32> f32mat4x4;
+	typedef detail::tmat4x4<f32, defaultp> f32mat4x4;
 
 
 	/// Double-precision floating-point 1x1 matrix. 
 	/// @see gtc_type_precision
-	//typedef detail::tmat1x1<f64> f64mat1;
+	//typedef detail::tmat1x1<f64, defaultp> f64mat1;
 
 	/// Double-precision floating-point 2x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f64> f64mat2;
+	typedef detail::tmat2x2<f64, defaultp> f64mat2;
 
 	/// Double-precision floating-point 3x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f64> f64mat3;
+	typedef detail::tmat3x3<f64, defaultp> f64mat3;
 
 	/// Double-precision floating-point 4x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f64> f64mat4;
+	typedef detail::tmat4x4<f64, defaultp> f64mat4;
 
 
 	/// Double-precision floating-point 1x1 matrix. 
@@ -611,55 +611,55 @@ namespace glm
 
 	/// Double-precision floating-point 2x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x2<f64> f64mat2x2;
+	typedef detail::tmat2x2<f64, defaultp> f64mat2x2;
 
 	/// Double-precision floating-point 2x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x3<f64> f64mat2x3;
+	typedef detail::tmat2x3<f64, defaultp> f64mat2x3;
 
 	/// Double-precision floating-point 2x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat2x4<f64> f64mat2x4;
+	typedef detail::tmat2x4<f64, defaultp> f64mat2x4;
 
 	/// Double-precision floating-point 3x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x2<f64> f64mat3x2;
+	typedef detail::tmat3x2<f64, defaultp> f64mat3x2;
 
 	/// Double-precision floating-point 3x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x3<f64> f64mat3x3;
+	typedef detail::tmat3x3<f64, defaultp> f64mat3x3;
 
 	/// Double-precision floating-point 3x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat3x4<f64> f64mat3x4;
+	typedef detail::tmat3x4<f64, defaultp> f64mat3x4;
 
 	/// Double-precision floating-point 4x2 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x2<f64> f64mat4x2;
+	typedef detail::tmat4x2<f64, defaultp> f64mat4x2;
 
 	/// Double-precision floating-point 4x3 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x3<f64> f64mat4x3;
+	typedef detail::tmat4x3<f64, defaultp> f64mat4x3;
 
 	/// Double-precision floating-point 4x4 matrix. 
 	/// @see gtc_type_precision
-	typedef detail::tmat4x4<f64> f64mat4x4;
+	typedef detail::tmat4x4<f64, defaultp> f64mat4x4;
 
 
 	//////////////////////////
 	// Quaternion types 
 
-	/// Half-precision floating-point quaternion. 
+	/// Half-precision floating-point quaternion.
 	/// @see gtc_type_precision
-	typedef detail::tquat<f16> f16quat;
+	typedef detail::tquat<f16, defaultp> f16quat;
 
-	/// Single-precision floating-point quaternion. 
+	/// Single-precision floating-point quaternion.
 	/// @see gtc_type_precision
-	typedef detail::tquat<f32> f32quat;
+	typedef detail::tquat<f32, defaultp> f32quat;
 
-	/// Double-precision floating-point quaternion. 
+	/// Double-precision floating-point quaternion.
 	/// @see gtc_type_precision
-	typedef detail::tquat<f64> f64quat;
+	typedef detail::tquat<f64, defaultp> f64quat;
 
 	/// @}
 }//namespace glm

+ 16 - 16
glm/gtc/type_ptr.hpp

@@ -82,83 +82,83 @@ namespace glm
 	/// Build a vector from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tvec2<T> make_vec2(T const * const ptr);
+	detail::tvec2<T, defaultp> make_vec2(T const * const ptr);
 
 	/// Build a vector from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tvec3<T> make_vec3(T const * const ptr);
+	detail::tvec3<T, defaultp> make_vec3(T const * const ptr);
 
 	/// Build a vector from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tvec4<T> make_vec4(T const * const ptr);
+	detail::tvec4<T, defaultp> make_vec4(T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat2x2<T> make_mat2x2(T const * const ptr);
+	detail::tmat2x2<T, defaultp> make_mat2x2(T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat2x3<T> make_mat2x3(T const * const ptr);
+	detail::tmat2x3<T, defaultp> make_mat2x3(T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat2x4<T> make_mat2x4(T const * const ptr);
+	detail::tmat2x4<T, defaultp> make_mat2x4(T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat3x2<T> make_mat3x2(T const * const ptr);
+	detail::tmat3x2<T, defaultp> make_mat3x2(T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat3x3<T> make_mat3x3(T const * const ptr);
+	detail::tmat3x3<T, defaultp> make_mat3x3(T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat3x4<T> make_mat3x4(T const * const ptr);
+	detail::tmat3x4<T, defaultp> make_mat3x4(T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat4x2<T> make_mat4x2(
+	detail::tmat4x2<T, defaultp> make_mat4x2(
 		T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat4x3<T> make_mat4x3(T const * const ptr);
+	detail::tmat4x3<T, defaultp> make_mat4x3(T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat4x4<T> make_mat4x4(T const * const ptr);
+	detail::tmat4x4<T, defaultp> make_mat4x4(T const * const ptr);
 	
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat2x2<T> make_mat2(T const * const ptr);
+	detail::tmat2x2<T, defaultp> make_mat2(T const * const ptr);
 
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat3x3<T> make_mat3(T const * const ptr);
+	detail::tmat3x3<T, defaultp> make_mat3(T const * const ptr);
 		
 	/// Build a matrix from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tmat4x4<T> make_mat4(T const * const ptr);
+	detail::tmat4x4<T, defaultp> make_mat4(T const * const ptr);
 
 	/// Build a quaternion from a pointer.
 	/// @see gtc_type_ptr
 	template<typename T>
-	detail::tquat<T> make_quat(T const * const ptr);
+	detail::tquat<T, defaultp> make_quat(T const * const ptr);
 
 	/// @}
 }//namespace glm

+ 108 - 108
glm/gtc/type_ptr.inl

@@ -33,10 +33,10 @@ namespace glm
 
 	/// Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tvec2<T> const & vec
+		detail::tvec2<T, P> const & vec
 	)
 	{
 		return &(vec.x);
@@ -44,10 +44,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(
-		detail::tvec2<T> & vec
+		detail::tvec2<T, P> & vec
 	)
 	{
 		return &(vec.x);
@@ -55,10 +55,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tvec3<T> const & vec
+		detail::tvec3<T, P> const & vec
 	)
 	{
 		return &(vec.x);
@@ -66,10 +66,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(
-		detail::tvec3<T> & vec
+		detail::tvec3<T, P> & vec
 	)
 	{
 		return &(vec.x);
@@ -77,10 +77,10 @@ namespace glm
 		
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(	
-		detail::tvec4<T> const & vec
+		detail::tvec4<T, P> const & vec
 	)
 	{
 		return &(vec.x);
@@ -88,10 +88,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	//! From GLM_GTC_type_ptr extension.
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(	
-		detail::tvec4<T> & vec
+		detail::tvec4<T, P> & vec
 	)
 	{
 		return &(vec.x);
@@ -99,10 +99,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tmat2x2<T> const & mat
+		detail::tmat2x2<T, P> const & mat
 	)
 	{
 		return &(mat[0].x);
@@ -110,10 +110,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(
-		detail::tmat2x2<T> & mat
+		detail::tmat2x2<T, P> & mat
 	)
 	{
 		return &(mat[0].x);
@@ -121,10 +121,10 @@ namespace glm
 		
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tmat3x3<T> const & mat
+		detail::tmat3x3<T, P> const & mat
 	)
 	{
 		return &(mat[0].x);
@@ -132,10 +132,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(
-		detail::tmat3x3<T> & mat
+		detail::tmat3x3<T, P> & mat
 	)
 	{
 		return &(mat[0].x);
@@ -143,10 +143,10 @@ namespace glm
 		
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tmat4x4<T> const & mat
+		detail::tmat4x4<T, P> const & mat
 	)
 	{
 		return &(mat[0].x);
@@ -154,10 +154,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	//! From GLM_GTC_type_ptr extension.
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(
-		detail::tmat4x4<T> & mat
+		detail::tmat4x4<T, P> & mat
 	)
 	{
 		return &(mat[0].x);
@@ -165,10 +165,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tmat2x3<T> const & mat
+		detail::tmat2x3<T, P> const & mat
 	)
 	{
 		return &(mat[0].x);
@@ -176,10 +176,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(
-		detail::tmat2x3<T> & mat
+		detail::tmat2x3<T, P> & mat
 	)
 	{
 		return &(mat[0].x);
@@ -187,10 +187,10 @@ namespace glm
 		
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tmat3x2<T> const & mat
+		detail::tmat3x2<T, P> const & mat
 	)
 	{
 		return &(mat[0].x);
@@ -198,10 +198,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(
-		detail::tmat3x2<T> & mat
+		detail::tmat3x2<T, P> & mat
 	)
 	{
 		return &(mat[0].x);
@@ -209,10 +209,10 @@ namespace glm
 		
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tmat2x4<T> const & mat
+		detail::tmat2x4<T, P> const & mat
 	)
 	{
 		return &(mat[0].x);
@@ -220,10 +220,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(
-		detail::tmat2x4<T> & mat
+		detail::tmat2x4<T, P> & mat
 	)
 	{
 		return &(mat[0].x);
@@ -231,10 +231,10 @@ namespace glm
 		
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tmat4x2<T> const & mat
+		detail::tmat4x2<T, P> const & mat
 	)
 	{
 		return &(mat[0].x);
@@ -242,10 +242,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(	
-		detail::tmat4x2<T> & mat
+		detail::tmat4x2<T, P> & mat
 	)
 	{
 		return &(mat[0].x);
@@ -253,10 +253,10 @@ namespace glm
 		
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tmat3x4<T> const & mat
+		detail::tmat3x4<T, P> const & mat
 	)
 	{
 		return &(mat[0].x);
@@ -264,10 +264,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T * value_ptr
 	(
-		detail::tmat3x4<T> & mat
+		detail::tmat3x4<T, P> & mat
 	)
 	{
 		return &(mat[0].x);
@@ -275,10 +275,10 @@ namespace glm
 		
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tmat4x3<T> const & mat
+		detail::tmat4x3<T, P> const & mat
 	)
 	{
 		return &(mat[0].x);
@@ -286,10 +286,10 @@ namespace glm
 
 	//! Return the constant address to the data of the input parameter.
 	/// @see gtc_type_ptr
-	template<typename T>
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER T const * value_ptr
 	(
-		detail::tquat<T> const & q
+		detail::tquat<T, P> const & q
 	)
 	{
 		return &(q[0]);
@@ -297,163 +297,163 @@ namespace glm
 
 	//! Get the address of the matrix content.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER T * value_ptr(detail::tmat4x3<T> & mat)
+	template<typename T, precision P>
+	GLM_FUNC_QUALIFIER T * value_ptr(detail::tmat4x3<T, P> & mat)
 	{
 		return &(mat[0].x);
 	}
 
 	//! Build a vector from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> make_vec2(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, defaultp> make_vec2(T const * const ptr)
 	{
-		detail::tvec2<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tvec2<T>));
+		detail::tvec2<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tvec2<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a vector from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> make_vec3(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, defaultp> make_vec3(T const * const ptr)
 	{
-		detail::tvec3<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tvec3<T>));
+		detail::tvec3<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tvec3<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a vector from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> make_vec4(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, defaultp> make_vec4(T const * const ptr)
 	{
-		detail::tvec4<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tvec4<T>));
+		detail::tvec4<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tvec4<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x2<T> make_mat2x2(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, defaultp> make_mat2x2(T const * const ptr)
 	{
-		detail::tmat2x2<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat2x2<T>));
+		detail::tmat2x2<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat2x2<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x3<T> make_mat2x3(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat2x3<T, defaultp> make_mat2x3(T const * const ptr)
 	{
-		detail::tmat2x3<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat2x3<T>));
+		detail::tmat2x3<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat2x3<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x4<T> make_mat2x4(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat2x4<T, defaultp> make_mat2x4(T const * const ptr)
 	{
-		detail::tmat2x4<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat2x4<T>));
+		detail::tmat2x4<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat2x4<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x2<T> make_mat3x2(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x2<T, defaultp> make_mat3x2(T const * const ptr)
 	{
-		detail::tmat3x2<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat3x2<T>));
+		detail::tmat3x2<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat3x2<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> make_mat3x3(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, defaultp> make_mat3x3(T const * const ptr)
 	{
-		detail::tmat3x3<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat3x3<T>));
+		detail::tmat3x3<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat3x3<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x4<T> make_mat3x4(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x4<T, defaultp> make_mat3x4(T const * const ptr)
 	{
-		detail::tmat3x4<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat3x4<T>));
+		detail::tmat3x4<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat3x4<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x2<T> make_mat4x2(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x2<T, defaultp> make_mat4x2(T const * const ptr)
 	{
-		detail::tmat4x2<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat4x2<T>));
+		detail::tmat4x2<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat4x2<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x3<T> make_mat4x3(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x3<T, defaultp> make_mat4x3(T const * const ptr)
 	{
-		detail::tmat4x3<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat4x3<T>));
+		detail::tmat4x3<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat4x3<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> make_mat4x4(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> make_mat4x4(T const * const ptr)
 	{
-		detail::tmat4x4<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat4x4<T>));
+		detail::tmat4x4<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tmat4x4<T, defaultp>));
 		return Result;
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x2<T> make_mat2(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, defaultp> make_mat2(T const * const ptr)
 	{
 		return make_mat2x2(ptr);
 	}
 
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> make_mat3(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, defaultp> make_mat3(T const * const ptr)
 	{
 		return make_mat3x3(ptr);
 	}
 		
 	//! Build a matrix from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> make_mat4(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> make_mat4(T const * const ptr)
 	{
 		return make_mat4x4(ptr);
 	}
 
 	//! Build a quaternion from a pointer.
 	/// @see gtc_type_ptr
-	template<typename T>
-	GLM_FUNC_QUALIFIER detail::tquat<T> make_quat(T const * const ptr)
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tquat<T, defaultp> make_quat(T const * const ptr)
 	{
-		detail::tquat<T> Result;
-		memcpy(value_ptr(Result), ptr, sizeof(detail::tquat<T>));
+		detail::tquat<T, defaultp> Result;
+		memcpy(value_ptr(Result), ptr, sizeof(detail::tquat<T, defaultp>));
 		return Result;
 	}
 

+ 114 - 114
glm/gtx/associated_min_max.inl

@@ -19,8 +19,8 @@ GLM_FUNC_QUALIFIER U associatedMin(T x, U a, T y, U b)
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 (
-	const detail::tvec2<T>& x, const detail::tvec2<U>& a,
-	const detail::tvec2<T>& y, const detail::tvec2<U>& b
+	const detail::tvec2<T, P>& x, const detail::tvec2<U>& a,
+	const detail::tvec2<T, P>& y, const detail::tvec2<U>& b
 )
 {
 	detail::tvec2<U> Result;
@@ -34,8 +34,8 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 (
-	const detail::tvec3<T>& x, const detail::tvec3<U>& a,
-	const detail::tvec3<T>& y, const detail::tvec3<U>& b
+	const detail::tvec3<T, P>& x, const detail::tvec3<U>& a,
+	const detail::tvec3<T, P>& y, const detail::tvec3<U>& b
 )
 {
 	detail::tvec3<U> Result;
@@ -47,8 +47,8 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
 (
-	const detail::tvec4<T>& x, const detail::tvec4<U>& a,
-	const detail::tvec4<T>& y, const detail::tvec4<U>& b
+	const detail::tvec4<T, P>& x, const detail::tvec4<U>& a,
+	const detail::tvec4<T, P>& y, const detail::tvec4<U>& b
 )
 {
 	detail::tvec4<U> Result;
@@ -99,12 +99,12 @@ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 (
-	const detail::tvec2<T>& x, U a,
-	const detail::tvec2<T>& y, U b
+	const detail::tvec2<T, P>& x, U a,
+	const detail::tvec2<T, P>& y, U b
 )
 {
 	detail::tvec2<U> Result;
-	for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+	for(typename detail::tvec2<U>::size_type i = 0; i < detail::tvec2<T, P>::value_size(); ++i)
 		Result[i] = x[i] < y[i] ? a : b;
 	return Result;
 }
@@ -112,12 +112,12 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 (
-	const detail::tvec3<T>& x, U a,
-	const detail::tvec3<T>& y, U b
+	const detail::tvec3<T, P>& x, U a,
+	const detail::tvec3<T, P>& y, U b
 )
 {
 	detail::tvec3<U> Result;
-	for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+	for(typename detail::tvec3<U>::size_type i = 0; i < detail::tvec3<T, P>::value_size(); ++i)
 		Result[i] = x[i] < y[i] ? a : b;
 	return Result;
 }
@@ -125,12 +125,12 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
 (
-	const detail::tvec4<T>& x, U a,
-	const detail::tvec4<T>& y, U b
+	const detail::tvec4<T, P>& x, U a,
+	const detail::tvec4<T, P>& y, U b
 )
 {
 	detail::tvec4<U> Result;
-	for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+	for(typename detail::tvec4<U>::size_type i = 0; i < detail::tvec4<T, P>::value_size(); ++i)
 		Result[i] = x[i] < y[i] ? a : b;
 	return Result;
 }
@@ -151,9 +151,9 @@ GLM_FUNC_QUALIFIER U associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 (
-	const detail::tvec2<T>& x, const detail::tvec2<U>& a,
-	const detail::tvec2<T>& y, const detail::tvec2<U>& b,
-	const detail::tvec2<T>& z, const detail::tvec2<U>& c
+	const detail::tvec2<T, P>& x, const detail::tvec2<U>& a,
+	const detail::tvec2<T, P>& y, const detail::tvec2<U>& b,
+	const detail::tvec2<T, P>& z, const detail::tvec2<U>& c
 )
 {
 	detail::tvec2<U> Result;
@@ -165,9 +165,9 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 (
-	const detail::tvec3<T>& x, const detail::tvec3<U>& a,
-	const detail::tvec3<T>& y, const detail::tvec3<U>& b,
-	const detail::tvec3<T>& z, const detail::tvec3<U>& c
+	const detail::tvec3<T, P>& x, const detail::tvec3<U>& a,
+	const detail::tvec3<T, P>& y, const detail::tvec3<U>& b,
+	const detail::tvec3<T, P>& z, const detail::tvec3<U>& c
 )
 {
 	detail::tvec3<U> Result;
@@ -179,9 +179,9 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
 (
-	const detail::tvec4<T>& x, const detail::tvec4<U>& a,
-	const detail::tvec4<T>& y, const detail::tvec4<U>& b,
-	const detail::tvec4<T>& z, const detail::tvec4<U>& c
+	const detail::tvec4<T, P>& x, const detail::tvec4<U>& a,
+	const detail::tvec4<T, P>& y, const detail::tvec4<U>& b,
+	const detail::tvec4<T, P>& z, const detail::tvec4<U>& c
 )
 {
 	detail::tvec4<U> Result;
@@ -212,10 +212,10 @@ GLM_FUNC_QUALIFIER U associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 (
-	const detail::tvec2<T>& x, const detail::tvec2<U>& a,
-	const detail::tvec2<T>& y, const detail::tvec2<U>& b,
-	const detail::tvec2<T>& z, const detail::tvec2<U>& c,
-	const detail::tvec2<T>& w, const detail::tvec2<U>& d
+	const detail::tvec2<T, P>& x, const detail::tvec2<U>& a,
+	const detail::tvec2<T, P>& y, const detail::tvec2<U>& b,
+	const detail::tvec2<T, P>& z, const detail::tvec2<U>& c,
+	const detail::tvec2<T, P>& w, const detail::tvec2<U>& d
 )
 {
 	detail::tvec2<U> Result;
@@ -234,10 +234,10 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 (
-	const detail::tvec3<T>& x, const detail::tvec3<U>& a,
-	const detail::tvec3<T>& y, const detail::tvec3<U>& b,
-	const detail::tvec3<T>& z, const detail::tvec3<U>& c,
-	const detail::tvec3<T>& w, const detail::tvec3<U>& d
+	const detail::tvec3<T, P>& x, const detail::tvec3<U>& a,
+	const detail::tvec3<T, P>& y, const detail::tvec3<U>& b,
+	const detail::tvec3<T, P>& z, const detail::tvec3<U>& c,
+	const detail::tvec3<T, P>& w, const detail::tvec3<U>& d
 )
 {
 	detail::tvec3<U> Result;
@@ -256,10 +256,10 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
 (
-	const detail::tvec4<T>& x, const detail::tvec4<U>& a,
-	const detail::tvec4<T>& y, const detail::tvec4<U>& b,
-	const detail::tvec4<T>& z, const detail::tvec4<U>& c,
-	const detail::tvec4<T>& w, const detail::tvec4<U>& d
+	const detail::tvec4<T, P>& x, const detail::tvec4<U>& a,
+	const detail::tvec4<T, P>& y, const detail::tvec4<U>& b,
+	const detail::tvec4<T, P>& z, const detail::tvec4<U>& c,
+	const detail::tvec4<T, P>& w, const detail::tvec4<U>& d
 )
 {
 	detail::tvec4<U> Result;
@@ -347,14 +347,14 @@ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 (
-	const detail::tvec2<T>& x, U a,
-	const detail::tvec2<T>& y, U b,
-	const detail::tvec2<T>& z, U c,
-	const detail::tvec2<T>& w, U d
+	const detail::tvec2<T, P>& x, U a,
+	const detail::tvec2<T, P>& y, U b,
+	const detail::tvec2<T, P>& z, U c,
+	const detail::tvec2<T, P>& w, U d
 )
 {
 	detail::tvec2<U> Result;
-	for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+	for(typename detail::tvec2<T, P>::size_type i = 0; i < detail::tvec2<T, P>::value_size(); ++i)
 	{
 		T Test1 = min(x[i], y[i]);
 		T Test2 = min(z[i], w[i]);;
@@ -369,14 +369,14 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 (
-	const detail::tvec3<T>& x, U a,
-	const detail::tvec3<T>& y, U b,
-	const detail::tvec3<T>& z, U c,
-	const detail::tvec3<T>& w, U d
+	const detail::tvec3<T, P>& x, U a,
+	const detail::tvec3<T, P>& y, U b,
+	const detail::tvec3<T, P>& z, U c,
+	const detail::tvec3<T, P>& w, U d
 )
 {
 	detail::tvec3<U> Result;
-	for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+	for(typename detail::tvec3<T, P>::size_type i = 0; i < detail::tvec3<T, P>::value_size(); ++i)
 	{
 		T Test1 = min(x[i], y[i]);
 		T Test2 = min(z[i], w[i]);;
@@ -391,14 +391,14 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMin
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMin
 (
-	const detail::tvec4<T>& x, U a,
-	const detail::tvec4<T>& y, U b,
-	const detail::tvec4<T>& z, U c,
-	const detail::tvec4<T>& w, U d
+	const detail::tvec4<T, P>& x, U a,
+	const detail::tvec4<T, P>& y, U b,
+	const detail::tvec4<T, P>& z, U c,
+	const detail::tvec4<T, P>& w, U d
 )
 {
 	detail::tvec4<U> Result;
-	for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+	for(typename detail::tvec4<T, P>::size_type i = 0; i < detail::tvec4<T, P>::value_size(); ++i)
 	{
 		T Test1 = min(x[i], y[i]);
 		T Test2 = min(z[i], w[i]);;
@@ -420,8 +420,8 @@ GLM_FUNC_QUALIFIER U associatedMax(T x, U a, T y, U b)
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 (
-	const detail::tvec2<T>& x, const detail::tvec2<U>& a,
-	const detail::tvec2<T>& y, const detail::tvec2<U>& b
+	const detail::tvec2<T, P>& x, const detail::tvec2<U>& a,
+	const detail::tvec2<T, P>& y, const detail::tvec2<U>& b
 )
 {
 	detail::tvec2<U> Result;
@@ -434,8 +434,8 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 (
-	const detail::tvec3<T>& x, const detail::tvec3<U>& a,
-	const detail::tvec3<T>& y, const detail::tvec3<U>& b
+	const detail::tvec3<T, P>& x, const detail::tvec3<U>& a,
+	const detail::tvec3<T, P>& y, const detail::tvec3<U>& b
 )
 {
 	detail::tvec3<U> Result;
@@ -448,8 +448,8 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
 (
-	const detail::tvec4<T>& x, const detail::tvec4<U>& a,
-	const detail::tvec4<T>& y, const detail::tvec4<U>& b
+	const detail::tvec4<T, P>& x, const detail::tvec4<U>& a,
+	const detail::tvec4<T, P>& y, const detail::tvec4<U>& b
 )
 {
 	detail::tvec4<U> Result;
@@ -504,12 +504,12 @@ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 (
-	const detail::tvec2<T>& x, U a,
-	const detail::tvec2<T>& y, U b
+	const detail::tvec2<T, P>& x, U a,
+	const detail::tvec2<T, P>& y, U b
 )
 {
 	detail::tvec2<U> Result;
-	for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+	for(typename detail::tvec2<T, P>::size_type i = 0; i < detail::tvec2<T, P>::value_size(); ++i)
 		Result[i] = x[i] > y[i] ? a : b;
 	return Result;
 }
@@ -518,12 +518,12 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 (
-	const detail::tvec3<T>& x, U a,
-	const detail::tvec3<T>& y, U b
+	const detail::tvec3<T, P>& x, U a,
+	const detail::tvec3<T, P>& y, U b
 )
 {
 	detail::tvec3<U> Result;
-	for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+	for(typename detail::tvec3<T, P>::size_type i = 0; i < detail::tvec3<T, P>::value_size(); ++i)
 		Result[i] = x[i] > y[i] ? a : b;
 	return Result;
 }
@@ -532,12 +532,12 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
 (
-	const detail::tvec4<T>& x, U a,
-	const detail::tvec4<T>& y, U b
+	const detail::tvec4<T, P>& x, U a,
+	const detail::tvec4<T, P>& y, U b
 )
 {
 	detail::tvec4<U> Result;
-	for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+	for(typename detail::tvec4<T, P>::size_type i = 0; i < detail::tvec4<T, P>::value_size(); ++i)
 		Result[i] = x[i] > y[i] ? a : b;
 	return Result;
 }
@@ -559,9 +559,9 @@ GLM_FUNC_QUALIFIER U associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 (
-	const detail::tvec2<T>& x, const detail::tvec2<U>& a,
-	const detail::tvec2<T>& y, const detail::tvec2<U>& b,
-	const detail::tvec2<T>& z, const detail::tvec2<U>& c
+	const detail::tvec2<T, P>& x, const detail::tvec2<U>& a,
+	const detail::tvec2<T, P>& y, const detail::tvec2<U>& b,
+	const detail::tvec2<T, P>& z, const detail::tvec2<U>& c
 )
 {
 	detail::tvec2<U> Result;
@@ -574,9 +574,9 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 (
-	const detail::tvec3<T>& x, const detail::tvec3<U>& a,
-	const detail::tvec3<T>& y, const detail::tvec3<U>& b,
-	const detail::tvec3<T>& z, const detail::tvec3<U>& c
+	const detail::tvec3<T, P>& x, const detail::tvec3<U>& a,
+	const detail::tvec3<T, P>& y, const detail::tvec3<U>& b,
+	const detail::tvec3<T, P>& z, const detail::tvec3<U>& c
 )
 {
 	detail::tvec3<U> Result;
@@ -589,9 +589,9 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
 (
-	const detail::tvec4<T>& x, const detail::tvec4<U>& a,
-	const detail::tvec4<T>& y, const detail::tvec4<U>& b,
-	const detail::tvec4<T>& z, const detail::tvec4<U>& c
+	const detail::tvec4<T, P>& x, const detail::tvec4<U>& a,
+	const detail::tvec4<T, P>& y, const detail::tvec4<U>& b,
+	const detail::tvec4<T, P>& z, const detail::tvec4<U>& c
 )
 {
 	detail::tvec4<U> Result;
@@ -649,13 +649,13 @@ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 (
-	const detail::tvec2<T>& x, U a,
-	const detail::tvec2<T>& y, U b,
-	const detail::tvec2<T>& z, U c
+	const detail::tvec2<T, P>& x, U a,
+	const detail::tvec2<T, P>& y, U b,
+	const detail::tvec2<T, P>& z, U c
 )
 {
 	detail::tvec2<U> Result;
-	for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+	for(typename detail::tvec2<T, P>::size_type i = 0; i < detail::tvec2<T, P>::value_size(); ++i)
 		Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
 	return Result;
 }
@@ -664,13 +664,13 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 (
-	const detail::tvec3<T>& x, U a,
-	const detail::tvec3<T>& y, U b,
-	const detail::tvec3<T>& z, U c
+	const detail::tvec3<T, P>& x, U a,
+	const detail::tvec3<T, P>& y, U b,
+	const detail::tvec3<T, P>& z, U c
 )
 {
 	detail::tvec3<U> Result;
-	for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+	for(typename detail::tvec3<T, P>::size_type i = 0; i < detail::tvec3<T, P>::value_size(); ++i)
 		Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
 	return Result;
 }
@@ -679,13 +679,13 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
 (
-	const detail::tvec4<T>& x, U a,
-	const detail::tvec4<T>& y, U b,
-	const detail::tvec4<T>& z, U c
+	const detail::tvec4<T, P>& x, U a,
+	const detail::tvec4<T, P>& y, U b,
+	const detail::tvec4<T, P>& z, U c
 )
 {
 	detail::tvec4<U> Result;
-	for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+	for(typename detail::tvec4<T, P>::size_type i = 0; i < detail::tvec4<T, P>::value_size(); ++i)
 		Result[i] = x[i] > y[i] ? (x[i] > z[i] ? a : c) : (y[i] > z[i] ? b : c);
 	return Result;
 }
@@ -712,10 +712,10 @@ GLM_FUNC_QUALIFIER U associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 (
-	const detail::tvec2<T>& x, const detail::tvec2<U>& a,
-	const detail::tvec2<T>& y, const detail::tvec2<U>& b,
-	const detail::tvec2<T>& z, const detail::tvec2<U>& c,
-	const detail::tvec2<T>& w, const detail::tvec2<U>& d
+	const detail::tvec2<T, P>& x, const detail::tvec2<U>& a,
+	const detail::tvec2<T, P>& y, const detail::tvec2<U>& b,
+	const detail::tvec2<T, P>& z, const detail::tvec2<U>& c,
+	const detail::tvec2<T, P>& w, const detail::tvec2<U>& d
 )
 {
 	detail::tvec2<U> Result;
@@ -734,10 +734,10 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 (
-	const detail::tvec3<T>& x, const detail::tvec3<U>& a,
-	const detail::tvec3<T>& y, const detail::tvec3<U>& b,
-	const detail::tvec3<T>& z, const detail::tvec3<U>& c,
-	const detail::tvec3<T>& w, const detail::tvec3<U>& d
+	const detail::tvec3<T, P>& x, const detail::tvec3<U>& a,
+	const detail::tvec3<T, P>& y, const detail::tvec3<U>& b,
+	const detail::tvec3<T, P>& z, const detail::tvec3<U>& c,
+	const detail::tvec3<T, P>& w, const detail::tvec3<U>& d
 )
 {
 	detail::tvec3<U> Result;
@@ -756,10 +756,10 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
 (
-	const detail::tvec4<T>& x, const detail::tvec4<U>& a,
-	const detail::tvec4<T>& y, const detail::tvec4<U>& b,
-	const detail::tvec4<T>& z, const detail::tvec4<U>& c,
-	const detail::tvec4<T>& w, const detail::tvec4<U>& d
+	const detail::tvec4<T, P>& x, const detail::tvec4<U>& a,
+	const detail::tvec4<T, P>& y, const detail::tvec4<U>& b,
+	const detail::tvec4<T, P>& z, const detail::tvec4<U>& c,
+	const detail::tvec4<T, P>& w, const detail::tvec4<U>& d
 )
 {
 	detail::tvec4<U> Result;
@@ -847,14 +847,14 @@ GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 (
-	const detail::tvec2<T>& x, U a,
-	const detail::tvec2<T>& y, U b,
-	const detail::tvec2<T>& z, U c,
-	const detail::tvec2<T>& w, U d
+	const detail::tvec2<T, P>& x, U a,
+	const detail::tvec2<T, P>& y, U b,
+	const detail::tvec2<T, P>& z, U c,
+	const detail::tvec2<T, P>& w, U d
 )
 {
 	detail::tvec2<U> Result;
-	for(typename detail::tvec2<T>::size_type i = 0; i < detail::tvec2<T>::value_size(); ++i)
+	for(typename detail::tvec2<T, P>::size_type i = 0; i < detail::tvec2<T, P>::value_size(); ++i)
 	{
 		T Test1 = max(x[i], y[i]);
 		T Test2 = max(z[i], w[i]);;
@@ -869,14 +869,14 @@ GLM_FUNC_QUALIFIER detail::tvec2<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 (
-	const detail::tvec3<T>& x, U a,
-	const detail::tvec3<T>& y, U b,
-	const detail::tvec3<T>& z, U c,
-	const detail::tvec3<T>& w, U d
+	const detail::tvec3<T, P>& x, U a,
+	const detail::tvec3<T, P>& y, U b,
+	const detail::tvec3<T, P>& z, U c,
+	const detail::tvec3<T, P>& w, U d
 )
 {
 	detail::tvec3<U> Result;
-	for(typename detail::tvec3<T>::size_type i = 0; i < detail::tvec3<T>::value_size(); ++i)
+	for(typename detail::tvec3<T, P>::size_type i = 0; i < detail::tvec3<T, P>::value_size(); ++i)
 	{
 		T Test1 = max(x[i], y[i]);
 		T Test2 = max(z[i], w[i]);;
@@ -891,14 +891,14 @@ GLM_FUNC_QUALIFIER detail::tvec3<U> associatedMax
 template<typename T, typename U>
 GLM_FUNC_QUALIFIER detail::tvec4<U> associatedMax
 (
-	const detail::tvec4<T>& x, U a,
-	const detail::tvec4<T>& y, U b,
-	const detail::tvec4<T>& z, U c,
-	const detail::tvec4<T>& w, U d
+	const detail::tvec4<T, P>& x, U a,
+	const detail::tvec4<T, P>& y, U b,
+	const detail::tvec4<T, P>& z, U c,
+	const detail::tvec4<T, P>& w, U d
 )
 {
 	detail::tvec4<U> Result;
-	for(typename detail::tvec4<T>::size_type i = 0; i < detail::tvec4<T>::value_size(); ++i)
+	for(typename detail::tvec4<T, P>::size_type i = 0; i < detail::tvec4<T, P>::value_size(); ++i)
 	{
 		T Test1 = max(x[i], y[i]);
 		T Test2 = max(z[i], w[i]);;

+ 124 - 124
glm/gtx/bit.inl

@@ -60,8 +60,8 @@ namespace glm
 	template <typename genIUType, typename sizeType>
 	GLM_FUNC_QUALIFIER genIUType extractField
 	(
-		genIUType const & Value, 
-		sizeType const & First, 
+		genIUType const & Value,
+		sizeType const & First,
 		sizeType const & Count
 	)
 	{
@@ -75,126 +75,126 @@ namespace glm
 		return ShiftBack;
 	}
 
-	template <typename genIUType, typename sizeType>
-	GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
+	template <typename T, precision P, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> extractField
 	(
-		detail::tvec2<genIUType> const & value, 
+		detail::tvec2<T, P> const & value,
 		sizeType const & first, 
 		sizeType const & count
 	)
 	{
-		return detail::tvec2<genIUType>(
+		return detail::tvec2<T, P>(
 			extractField(value[0], first, count),
 			extractField(value[1], first, count));
 	}
 
-	template <typename genIUType, typename sizeType>
-	GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
+	template <typename T, precision P, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> extractField
 	(
-		detail::tvec3<genIUType> const & value, 
-		sizeType const & first, 
+		detail::tvec3<T, P> const & value,
+		sizeType const & first,
 		sizeType const & count
 	)
 	{
-		return detail::tvec3<genIUType>(
+		return detail::tvec3<T, P>(
 			extractField(value[0], first, count),
 			extractField(value[1], first, count),
 			extractField(value[2], first, count));
 	}
 
-	template <typename genIUType, typename sizeType>
-	GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
+	template <typename T, precision P, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> extractField
 	(
-		detail::tvec4<genIUType> const & value, 
-		sizeType const & first, 
+		detail::tvec4<T, P> const & value,
+		sizeType const & first,
 		sizeType const & count
 	)
 	{
-		return detail::tvec4<genIUType>(
+		return detail::tvec4<T, P>(
 			extractField(value[0], first, count),
 			extractField(value[1], first, count),
 			extractField(value[2], first, count),
 			extractField(value[3], first, count));
 	}
 
-	template <typename genIUType, typename sizeType>
-	GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
+	template <typename T, precision P, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> extractField
 	(
-		detail::tvec2<genIUType> const & value, 
-		detail::tvec2<sizeType> const & first, 
-		detail::tvec2<sizeType> const & count
+		detail::tvec2<T, P> const & value, 
+		detail::tvec2<sizeType, P> const & first, 
+		detail::tvec2<sizeType, P> const & count
 	)
 	{
-		return detail::tvec2<genIUType>(
+		return detail::tvec2<T, P>(
 			extractField(value[0], first[0], count[0]),
 			extractField(value[1], first[1], count[1]));
 	}
 
-	template <typename genIUType, typename sizeType>
-	GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
+	template <typename T, precision P, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> extractField
 	(
-		detail::tvec3<genIUType> const & value, 
-		detail::tvec3<sizeType> const & first, 
-		detail::tvec3<sizeType> const & count
+		detail::tvec3<T, P> const & value, 
+		detail::tvec3<sizeType, P> const & first, 
+		detail::tvec3<sizeType, P> const & count
 	)
 	{
-		return detail::tvec3<genIUType>(
+		return detail::tvec3<T, P>(
 			extractField(value[0], first[0], count[0]),
 			extractField(value[1], first[1], count[1]),
 			extractField(value[2], first[2], count[2]));
 	}
 
-	template <typename genIUType, typename sizeType>
-	GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
+	template <typename T, precision P, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> extractField
 	(
-		detail::tvec4<genIUType> const & value, 
-		detail::tvec4<sizeType> const & first, 
-		detail::tvec4<sizeType> const & count
+		detail::tvec4<T, P> const & value, 
+		detail::tvec4<sizeType, P> const & first, 
+		detail::tvec4<sizeType, P> const & count
 	)
 	{
-		return detail::tvec4<genIUType>(
+		return detail::tvec4<T, P>(
 			extractField(value[0], first[0], count[0]),
 			extractField(value[1], first[1], count[1]),
 			extractField(value[2], first[2], count[2]),
 			extractField(value[3], first[3], count[3]));
 	}
 
-	template <typename genIUType, typename sizeType>
-	GLM_FUNC_QUALIFIER detail::tvec2<genIUType> extractField
+	template <typename T, precision P, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> extractField
 	(
-		genIUType const & value, 
-		detail::tvec2<sizeType> const & first, 
-		detail::tvec2<sizeType> const & count
+		T const & value, 
+		detail::tvec2<sizeType, P> const & first, 
+		detail::tvec2<sizeType, P> const & count
 	)
 	{
-		return detail::tvec2<genIUType>(
+		return detail::tvec2<T, P>(
 			extractField(value, first[0], count[0]),
 			extractField(value, first[1], count[1]));
 	}
 
-	template <typename genIUType, typename sizeType>
-	GLM_FUNC_QUALIFIER detail::tvec3<genIUType> extractField
+	template <typename T, precision P, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> extractField
 	(
-		genIUType const & value, 
-		detail::tvec3<sizeType> const & first, 
-		detail::tvec3<sizeType> const & count
+		T const & value,
+		detail::tvec3<sizeType, P> const & first,
+		detail::tvec3<sizeType, P> const & count
 	)
 	{
-		return detail::tvec3<genIUType>(
+		return detail::tvec3<T, P>(
 			extractField(value, first[0], count[0]),
 			extractField(value, first[1], count[1]),
 			extractField(value, first[2], count[2]));
 	}
 
-	template <typename genIUType, typename sizeType>
-	GLM_FUNC_QUALIFIER detail::tvec4<genIUType> extractField
+	template <typename T, precision P, typename sizeType>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> extractField
 	(
-		genIUType const & value, 
-		detail::tvec4<sizeType> const & first, 
-		detail::tvec4<sizeType> const & count
+		T const & value,
+		detail::tvec4<sizeType, P> const & first,
+		detail::tvec4<sizeType, P> const & count
 	)
 	{
-		return detail::tvec4<genIUType>(
+		return detail::tvec4<T, P>(
 			extractField(value, first[0], count[0]),
 			extractField(value, first[1], count[1]),
 			extractField(value, first[2], count[2]),
@@ -215,36 +215,36 @@ namespace glm
 		return Bit;
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<int> lowestBit
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<int, P> lowestBit
 	(
-		detail::tvec2<valType> const & value
+		detail::tvec2<T, P> const & value
 	)
 	{
-		return detail::tvec2<int>(
+		return detail::tvec2<int, P>(
 			lowestBit(value[0]),
 			lowestBit(value[1]));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<int> lowestBit
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<int, P> lowestBit
 	(
-		detail::tvec3<valType> const & value
+		detail::tvec3<T, P> const & value
 	)
 	{
-		return detail::tvec3<int>(
+		return detail::tvec3<int, P>(
 			lowestBit(value[0]),
 			lowestBit(value[1]),
 			lowestBit(value[2]));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<int> lowestBit
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<int, P> lowestBit
 	(
-		detail::tvec4<valType> const & value
+		detail::tvec4<T, P> const & value
 	)
 	{
-		return detail::tvec4<int>(
+		return detail::tvec4<int, P>(
 			lowestBit(value[0]),
 			lowestBit(value[1]),
 			lowestBit(value[2]),
@@ -276,36 +276,36 @@ namespace glm
 	//	return bit;
 	//}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<int> highestBit
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<int, P> highestBit
 	(
-		detail::tvec2<valType> const & value
+		detail::tvec2<T, P> const & value
 	)
 	{
-		return detail::tvec2<int>(
+		return detail::tvec2<int, P>(
 			highestBit(value[0]),
 			highestBit(value[1]));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<int> highestBit
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<int, P> highestBit
 	(
-		detail::tvec3<valType> const & value
+		detail::tvec3<T, P> const & value
 	)
 	{
-		return detail::tvec3<int>(
+		return detail::tvec3<int, P>(
 			highestBit(value[0]),
 			highestBit(value[1]),
 			highestBit(value[2]));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<int> highestBit
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<int, P> highestBit
 	(
-		detail::tvec4<valType> const & value
+		detail::tvec4<T, P> const & value
 	)
 	{
-		return detail::tvec4<int>(
+		return detail::tvec4<int, P>(
 			highestBit(value[0]),
 			highestBit(value[1]),
 			highestBit(value[2]),
@@ -329,36 +329,36 @@ namespace glm
 		return result;
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<int> highestBitValue
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<int, P> highestBitValue
 	(
-		detail::tvec2<valType> const & value
+		detail::tvec2<T, P> const & value
 	)
 	{
-		return detail::tvec2<int>(
+		return detail::tvec2<int, P>(
 			highestBitValue(value[0]),
 			highestBitValue(value[1]));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<int> highestBitValue
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<int, P> highestBitValue
 	(
-		detail::tvec3<valType> const & value
+		detail::tvec3<T, P> const & value
 	)
 	{
-		return detail::tvec3<int>(
+		return detail::tvec3<int, P>(
 			highestBitValue(value[0]),
 			highestBitValue(value[1]),
 			highestBitValue(value[2]));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<int> highestBitValue
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<int, P> highestBitValue
 	(
-		detail::tvec4<valType> const & value
+		detail::tvec4<T, P> const & value
 	)
 	{
-		return detail::tvec4<int>(
+		return detail::tvec4<int, P>(
 			highestBitValue(value[0]),
 			highestBitValue(value[1]),
 			highestBitValue(value[2]),
@@ -379,36 +379,36 @@ namespace glm
 		return !(Result & (Result - 1));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<bool> isPowerOfTwo
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool, P> isPowerOfTwo
 	(
-		detail::tvec2<valType> const & value
+		detail::tvec2<T, P> const & value
 	)
 	{
-		return detail::tvec2<bool>(
+		return detail::tvec2<bool, P>(
 			isPowerOfTwo(value[0]),
 			isPowerOfTwo(value[1]));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<bool> isPowerOfTwo
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool, P> isPowerOfTwo
 	(
-		detail::tvec3<valType> const & value
+		detail::tvec3<T, P> const & value
 	)
 	{
-		return detail::tvec3<bool>(
+		return detail::tvec3<bool, P>(
 			isPowerOfTwo(value[0]),
 			isPowerOfTwo(value[1]),
 			isPowerOfTwo(value[2]));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<bool> isPowerOfTwo
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> isPowerOfTwo
 	(
-		detail::tvec4<valType> const & value
+		detail::tvec4<T, P> const & value
 	)
 	{
-		return detail::tvec4<bool>(
+		return detail::tvec4<bool, P>(
 			isPowerOfTwo(value[0]),
 			isPowerOfTwo(value[1]),
 			isPowerOfTwo(value[2]),
@@ -477,39 +477,39 @@ namespace glm
 		return (In << Shift) | (In >> (BitSize - Shift));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateRight
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitRotateRight
 	(
-		detail::tvec2<valType> const & Value, 
+		detail::tvec2<T, P> const & Value, 
 		std::size_t Shift
 	)
 	{
-		return detail::tvec2<valType>(
+		return detail::tvec2<T, P>(
 			bitRotateRight(Value[0], Shift),
 			bitRotateRight(Value[1], Shift));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateRight
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitRotateRight
 	(
-		detail::tvec3<valType> const & Value, 
+		detail::tvec3<T, P> const & Value, 
 		std::size_t Shift
 	)
 	{
-		return detail::tvec3<valType>(
+		return detail::tvec3<T, P>(
 			bitRotateRight(Value[0], Shift),
 			bitRotateRight(Value[1], Shift),
 			bitRotateRight(Value[2], Shift));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateRight
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitRotateRight
 	(
-		detail::tvec4<valType> const & Value, 
+		detail::tvec4<T, P> const & Value, 
 		std::size_t Shift
 	)
 	{
-		return detail::tvec4<valType>(
+		return detail::tvec4<T, P>(
 			bitRotateRight(Value[0], Shift),
 			bitRotateRight(Value[1], Shift),
 			bitRotateRight(Value[2], Shift),
@@ -525,39 +525,39 @@ namespace glm
 		return (In >> Shift) | (In << (BitSize - Shift));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<valType> bitRotateLeft
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> bitRotateLeft
 	(
-		detail::tvec2<valType> const & Value, 
+		detail::tvec2<T, P> const & Value, 
 		std::size_t Shift
 	)
 	{
-		return detail::tvec2<valType>(
+		return detail::tvec2<T, P>(
 			bitRotateLeft(Value[0], Shift),
 			bitRotateLeft(Value[1], Shift));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<valType> bitRotateLeft
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> bitRotateLeft
 	(
-		detail::tvec3<valType> const & Value, 
+		detail::tvec3<T, P> const & Value, 
 		std::size_t Shift
 	)
 	{
-		return detail::tvec3<valType>(
+		return detail::tvec3<T, P>(
 			bitRotateLeft(Value[0], Shift),
 			bitRotateLeft(Value[1], Shift),
 			bitRotateLeft(Value[2], Shift));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<valType> bitRotateLeft
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> bitRotateLeft
 	(
-		detail::tvec4<valType> const & Value, 
+		detail::tvec4<T, P> const & Value, 
 		std::size_t Shift
 	)
 	{
-		return detail::tvec4<valType>(
+		return detail::tvec4<T, P>(
 			bitRotateLeft(Value[0], Shift),
 			bitRotateLeft(Value[1], Shift),
 			bitRotateLeft(Value[2], Shift),

+ 4 - 4
glm/gtx/closest_point.hpp

@@ -53,10 +53,10 @@ namespace glm
 	/// Find the point on a straight line which is the closet of a point. 
 	/// @see gtx_closest_point
 	template <typename T> 
-	detail::tvec3<T> closestPointOnLine(
-		detail::tvec3<T> const & point, 
-		detail::tvec3<T> const & a, 
-		detail::tvec3<T> const & b);
+	detail::tvec3<T, P> closestPointOnLine(
+		detail::tvec3<T, P> const & point, 
+		detail::tvec3<T, P> const & a, 
+		detail::tvec3<T, P> const & b);
 
 	/// @}
 }// namespace glm

+ 19 - 19
glm/gtx/color_cast.hpp

@@ -60,25 +60,25 @@ namespace glm
 	/// @see gtx_color_cast
 	template <typename valType>	uint16 u16channel_cast(valType a);
 
-	template <typename T> uint32 u32_rgbx_cast(const detail::tvec3<T>& c);		//!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint32 u32_xrgb_cast(const detail::tvec3<T>& c);		//!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint32 u32_bgrx_cast(const detail::tvec3<T>& c);		//!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint32 u32_xbgr_cast(const detail::tvec3<T>& c);		//!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
-
-	template <typename T> uint32 u32_rgba_cast(const detail::tvec4<T>& c);		//!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint32 u32_argb_cast(const detail::tvec4<T>& c);		//!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint32 u32_bgra_cast(const detail::tvec4<T>& c);		//!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint32 u32_abgr_cast(const detail::tvec4<T>& c);		//!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
-
-	template <typename T> uint64 u64_rgbx_cast(const detail::tvec3<T>& c);		//!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint64 u64_xrgb_cast(const detail::tvec3<T>& c);		//!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint64 u64_bgrx_cast(const detail::tvec3<T>& c);		//!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint64 u64_xbgr_cast(const detail::tvec3<T>& c);		//!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
-
-	template <typename T> uint64 u64_rgba_cast(const detail::tvec4<T>& c);		//!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint64 u64_argb_cast(const detail::tvec4<T>& c);		//!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint64 u64_bgra_cast(const detail::tvec4<T>& c);		//!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
-	template <typename T> uint64 u64_abgr_cast(const detail::tvec4<T>& c);		//!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint32 u32_rgbx_cast(const detail::tvec3<T, P>& c);		//!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint32 u32_xrgb_cast(const detail::tvec3<T, P>& c);		//!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint32 u32_bgrx_cast(const detail::tvec3<T, P>& c);		//!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint32 u32_xbgr_cast(const detail::tvec3<T, P>& c);		//!< \brief Conversion of a 3 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> uint32 u32_rgba_cast(const detail::tvec4<T, P>& c);		//!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint32 u32_argb_cast(const detail::tvec4<T, P>& c);		//!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint32 u32_bgra_cast(const detail::tvec4<T, P>& c);		//!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint32 u32_abgr_cast(const detail::tvec4<T, P>& c);		//!< \brief Conversion of a 4 components color into an 32bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> uint64 u64_rgbx_cast(const detail::tvec3<T, P>& c);		//!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint64 u64_xrgb_cast(const detail::tvec3<T, P>& c);		//!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint64 u64_bgrx_cast(const detail::tvec3<T, P>& c);		//!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint64 u64_xbgr_cast(const detail::tvec3<T, P>& c);		//!< \brief Conversion of a 3 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+
+	template <typename T> uint64 u64_rgba_cast(const detail::tvec4<T, P>& c);		//!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint64 u64_argb_cast(const detail::tvec4<T, P>& c);		//!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint64 u64_bgra_cast(const detail::tvec4<T, P>& c);		//!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
+	template <typename T> uint64 u64_abgr_cast(const detail::tvec4<T, P>& c);		//!< \brief Conversion of a 4 components color into an 64bit unsigned int value. (From GLM_GTX_color_cast extension)
 
 	template <typename T> f16 f16_channel_cast(T a);	//!< \brief Conversion of a u8 or u16 value to a single channel floating value. (From GLM_GTX_color_cast extension)
 

+ 74 - 74
glm/gtx/color_cast.inl

@@ -22,172 +22,172 @@ namespace glm
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint32 u32_rgbx_cast(const detail::tvec3<T>& c)
+	GLM_FUNC_QUALIFIER uint32 u32_rgbx_cast(const detail::tvec3<T, P>& c)
 	{
 		uint32 result = 0;
-		result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) <<  0;
-		result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) <<  8;
-		result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.x * detail::tvec3<T, P>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.y * detail::tvec3<T, P>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.z * detail::tvec3<T, P>::value_type(255)) << 16;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint32 u32_xrgb_cast(const detail::tvec3<T>& c)
+	GLM_FUNC_QUALIFIER uint32 u32_xrgb_cast(const detail::tvec3<T, P>& c)
 	{
 		uint32 result = 0;
-		result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) <<  8;
-		result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) << 16;
-		result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) << 24;
+		result += static_cast<uint32>(c.x * detail::tvec3<T, P>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.y * detail::tvec3<T, P>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.z * detail::tvec3<T, P>::value_type(255)) << 24;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint32 u32_bgrx_cast(const detail::tvec3<T>& c)
+	GLM_FUNC_QUALIFIER uint32 u32_bgrx_cast(const detail::tvec3<T, P>& c)
 	{
 		uint32 result = 0;
-		result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) << 16;
-		result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) <<  8;
-		result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.x * detail::tvec3<T, P>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.y * detail::tvec3<T, P>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.z * detail::tvec3<T, P>::value_type(255)) <<  0;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint32 u32_xbgr_cast(const detail::tvec3<T>& c)
+	GLM_FUNC_QUALIFIER uint32 u32_xbgr_cast(const detail::tvec3<T, P>& c)
 	{
 		uint32 result = 0;
-		result += static_cast<uint32>(c.x * detail::tvec3<T>::value_type(255)) << 24;
-		result += static_cast<uint32>(c.y * detail::tvec3<T>::value_type(255)) << 16;
-		result += static_cast<uint32>(c.z * detail::tvec3<T>::value_type(255)) <<  8;
-		result += static_cast<uint32>(c.w * detail::tvec3<T>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.x * detail::tvec3<T, P>::value_type(255)) << 24;
+		result += static_cast<uint32>(c.y * detail::tvec3<T, P>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.z * detail::tvec3<T, P>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.w * detail::tvec3<T, P>::value_type(255)) <<  0;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint32 u32_rgba_cast(const detail::tvec4<T>& c)
+	GLM_FUNC_QUALIFIER uint32 u32_rgba_cast(const detail::tvec4<T, P>& c)
 	{
 		uint32 result = 0;
-		result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) <<  0;
-		result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) <<  8;
-		result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) << 16;
-		result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) << 24;
+		result += static_cast<uint32>(c.x * detail::tvec4<T, P>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.y * detail::tvec4<T, P>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.z * detail::tvec4<T, P>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.w * detail::tvec4<T, P>::value_type(255)) << 24;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint32 u32_argb_cast(const detail::tvec4<T>& c)
+	GLM_FUNC_QUALIFIER uint32 u32_argb_cast(const detail::tvec4<T, P>& c)
 	{
 		uint32 result = 0;
-		result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) <<  8;
-		result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) << 16;
-		result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) << 24;
-		result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.x * detail::tvec4<T, P>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.y * detail::tvec4<T, P>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.z * detail::tvec4<T, P>::value_type(255)) << 24;
+		result += static_cast<uint32>(c.w * detail::tvec4<T, P>::value_type(255)) <<  0;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint32 u32_bgra_cast(const detail::tvec4<T>& c)
+	GLM_FUNC_QUALIFIER uint32 u32_bgra_cast(const detail::tvec4<T, P>& c)
 	{
 		uint32 result = 0;
-		result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) << 16;
-		result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) <<  8;
-		result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) <<  0;
-		result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) << 24;
+		result += static_cast<uint32>(c.x * detail::tvec4<T, P>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.y * detail::tvec4<T, P>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.z * detail::tvec4<T, P>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.w * detail::tvec4<T, P>::value_type(255)) << 24;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint32 u32_abgr_cast(const detail::tvec4<T>& c)
+	GLM_FUNC_QUALIFIER uint32 u32_abgr_cast(const detail::tvec4<T, P>& c)
 	{
 		uint32 result = 0;
-		result += static_cast<uint32>(c.x * detail::tvec4<T>::value_type(255)) << 24;
-		result += static_cast<uint32>(c.y * detail::tvec4<T>::value_type(255)) << 16;
-		result += static_cast<uint32>(c.z * detail::tvec4<T>::value_type(255)) <<  8;
-		result += static_cast<uint32>(c.w * detail::tvec4<T>::value_type(255)) <<  0;
+		result += static_cast<uint32>(c.x * detail::tvec4<T, P>::value_type(255)) << 24;
+		result += static_cast<uint32>(c.y * detail::tvec4<T, P>::value_type(255)) << 16;
+		result += static_cast<uint32>(c.z * detail::tvec4<T, P>::value_type(255)) <<  8;
+		result += static_cast<uint32>(c.w * detail::tvec4<T, P>::value_type(255)) <<  0;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint64 u64_rgbx_cast(const detail::tvec3<T>& c)
+	GLM_FUNC_QUALIFIER uint64 u64_rgbx_cast(const detail::tvec3<T, P>& c)
 	{
 		uint64 result = 0;
-		result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) <<  0;
-		result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 16;
-		result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.x * detail::tvec3<T, P>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.y * detail::tvec3<T, P>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.z * detail::tvec3<T, P>::value_type(65535)) << 32;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint64 u32_xrgb_cast(const detail::tvec3<T>& c)
+	GLM_FUNC_QUALIFIER uint64 u32_xrgb_cast(const detail::tvec3<T, P>& c)
 	{
 		uint64 result = 0;
-		result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 16;
-		result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 32;
-		result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 48;
+		result += static_cast<uint64>(c.x * detail::tvec3<T, P>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.y * detail::tvec3<T, P>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.z * detail::tvec3<T, P>::value_type(65535)) << 48;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint64 u32_bgrx_cast(const detail::tvec3<T>& c)
+	GLM_FUNC_QUALIFIER uint64 u32_bgrx_cast(const detail::tvec3<T, P>& c)
 	{
 		uint64 result = 0;
-		result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 32;
-		result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 16;
-		result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.x * detail::tvec3<T, P>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.y * detail::tvec3<T, P>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.z * detail::tvec3<T, P>::value_type(65535)) <<  0;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint64 u32_xbgr_cast(const detail::tvec3<T>& c)
+	GLM_FUNC_QUALIFIER uint64 u32_xbgr_cast(const detail::tvec3<T, P>& c)
 	{
 		uint64 result = 0;
-		result += static_cast<uint64>(c.x * detail::tvec3<T>::value_type(65535)) << 48;
-		result += static_cast<uint64>(c.y * detail::tvec3<T>::value_type(65535)) << 32;
-		result += static_cast<uint64>(c.z * detail::tvec3<T>::value_type(65535)) << 16;
-		result += static_cast<uint64>(c.w * detail::tvec3<T>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.x * detail::tvec3<T, P>::value_type(65535)) << 48;
+		result += static_cast<uint64>(c.y * detail::tvec3<T, P>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.z * detail::tvec3<T, P>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.w * detail::tvec3<T, P>::value_type(65535)) <<  0;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint64 u64_rgba_cast(const detail::tvec4<T>& c)
+	GLM_FUNC_QUALIFIER uint64 u64_rgba_cast(const detail::tvec4<T, P>& c)
 	{
 		uint64 result = 0;
-		result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) <<  0;
-		result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 16;
-		result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 32;
-		result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 48;
+		result += static_cast<uint64>(c.x * detail::tvec4<T, P>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.y * detail::tvec4<T, P>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.z * detail::tvec4<T, P>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.w * detail::tvec4<T, P>::value_type(65535)) << 48;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint64 u64_argb_cast(const detail::tvec4<T>& c)
+	GLM_FUNC_QUALIFIER uint64 u64_argb_cast(const detail::tvec4<T, P>& c)
 	{
 		uint64 result = 0;
-		result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 16;
-		result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 32;
-		result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 48;
-		result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.x * detail::tvec4<T, P>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.y * detail::tvec4<T, P>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.z * detail::tvec4<T, P>::value_type(65535)) << 48;
+		result += static_cast<uint64>(c.w * detail::tvec4<T, P>::value_type(65535)) <<  0;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint64 u64_bgra_cast(const detail::tvec4<T>& c)
+	GLM_FUNC_QUALIFIER uint64 u64_bgra_cast(const detail::tvec4<T, P>& c)
 	{
 		uint64 result = 0;
-		result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 32;
-		result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 16;
-		result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) <<  0;
-		result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) << 48;
+		result += static_cast<uint64>(c.x * detail::tvec4<T, P>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.y * detail::tvec4<T, P>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.z * detail::tvec4<T, P>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.w * detail::tvec4<T, P>::value_type(65535)) << 48;
 		return result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER uint64 u64_abgr_cast(const detail::tvec4<T>& c)
+	GLM_FUNC_QUALIFIER uint64 u64_abgr_cast(const detail::tvec4<T, P>& c)
 	{
 		uint64 result = 0;
-		result += static_cast<uint64>(c.x * detail::tvec4<T>::value_type(65535)) << 48;
-		result += static_cast<uint64>(c.y * detail::tvec4<T>::value_type(65535)) << 32;
-		result += static_cast<uint64>(c.z * detail::tvec4<T>::value_type(65535)) << 16;
-		result += static_cast<uint64>(c.w * detail::tvec4<T>::value_type(65535)) <<  0;
+		result += static_cast<uint64>(c.x * detail::tvec4<T, P>::value_type(65535)) << 48;
+		result += static_cast<uint64>(c.y * detail::tvec4<T, P>::value_type(65535)) << 32;
+		result += static_cast<uint64>(c.z * detail::tvec4<T, P>::value_type(65535)) << 16;
+		result += static_cast<uint64>(c.w * detail::tvec4<T, P>::value_type(65535)) <<  0;
 		return result;
 	}
 

+ 14 - 14
glm/gtx/color_space.inl

@@ -10,14 +10,14 @@
 namespace glm
 {
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec3<T> rgbColor(const detail::tvec3<T>& hsvColor)
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> rgbColor(const detail::tvec3<T, P>& hsvColor)
 	{
-		detail::tvec3<T> hsv = hsvColor;
-		detail::tvec3<T> rgbColor;
+		detail::tvec3<T, P> hsv = hsvColor;
+		detail::tvec3<T, P> rgbColor;
 
 		if(hsv.y == T(0))
 			// achromatic (grey)
-			rgbColor = detail::tvec3<T>(hsv.z);
+			rgbColor = detail::tvec3<T, P>(hsv.z);
 		else
 		{
 			T sector = floor(hsv.x / T(60));
@@ -67,9 +67,9 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec3<T> hsvColor(const detail::tvec3<T>& rgbColor)
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> hsvColor(const detail::tvec3<T, P>& rgbColor)
 	{
-		detail::tvec3<T> hsv = rgbColor;
+		detail::tvec3<T, P> hsv = rgbColor;
 		float Min   = min(min(rgbColor.r, rgbColor.g), rgbColor.b);
 		float Max   = max(max(rgbColor.r, rgbColor.g), rgbColor.b);
 		float Delta = Max - Min;
@@ -107,15 +107,15 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> saturation(const T s)
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> saturation(const T s)
 	{
-		detail::tvec3<T> rgbw = detail::tvec3<T>(T(0.2126), T(0.7152), T(0.0722));
+		detail::tvec3<T, P> rgbw = detail::tvec3<T, P>(T(0.2126), T(0.7152), T(0.0722));
 
 		T col0 = (T(1) - s) * rgbw.r;
 		T col1 = (T(1) - s) * rgbw.g;
 		T col2 = (T(1) - s) * rgbw.b;
 
-		detail::tmat4x4<T> result(T(1));
+		detail::tmat4x4<T, P> result(T(1));
 		result[0][0] = col0 + s;
 		result[0][1] = col0;
 		result[0][2] = col0;
@@ -129,21 +129,21 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec3<T> saturation(const T s, const detail::tvec3<T>& color)
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> saturation(const T s, const detail::tvec3<T, P>& color)
 	{
-		return detail::tvec3<T>(saturation(s) * detail::tvec4<T>(color, T(0)));
+		return detail::tvec3<T, P>(saturation(s) * detail::tvec4<T, P>(color, T(0)));
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec4<T> saturation(const T s, const detail::tvec4<T>& color)
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> saturation(const T s, const detail::tvec4<T, P>& color)
 	{
 		return saturation(s) * color;
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER T luminosity(const detail::tvec3<T>& color)
+	GLM_FUNC_QUALIFIER T luminosity(const detail::tvec3<T, P>& color)
 	{
-		const detail::tvec3<T> tmp = detail::tvec3<T>(0.33, 0.59, 0.11);
+		const detail::tvec3<T, P> tmp = detail::tvec3<T, P>(0.33, 0.59, 0.11);
 		return dot(color, tmp);
 	}
 }//namespace glm

+ 13 - 13
glm/gtx/compatibility.hpp

@@ -63,24 +63,24 @@ namespace glm
 	/// @{
 
 	template <typename T> GLM_FUNC_QUALIFIER T lerp(T x, T y, T a){return mix(x, y, a);}																					//!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T> lerp(const detail::tvec2<T>& x, const detail::tvec2<T>& y, T a){return mix(x, y, a);}							//!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T> lerp(const detail::tvec3<T>& x, const detail::tvec3<T>& y, T a){return mix(x, y, a);}							//!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T> lerp(const detail::tvec4<T>& x, const detail::tvec4<T>& y, T a){return mix(x, y, a);}							//!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T> lerp(const detail::tvec2<T>& x, const detail::tvec2<T>& y, const detail::tvec2<T>& a){return mix(x, y, a);}	//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T> lerp(const detail::tvec3<T>& x, const detail::tvec3<T>& y, const detail::tvec3<T>& a){return mix(x, y, a);}	//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T> lerp(const detail::tvec4<T>& x, const detail::tvec4<T>& y, const detail::tvec4<T>& a){return mix(x, y, a);}	//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T, P> lerp(const detail::tvec2<T, P>& x, const detail::tvec2<T, P>& y, T a){return mix(x, y, a);}							//!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T, P> lerp(const detail::tvec3<T, P>& x, const detail::tvec3<T, P>& y, T a){return mix(x, y, a);}							//!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T, P> lerp(const detail::tvec4<T, P>& x, const detail::tvec4<T, P>& y, T a){return mix(x, y, a);}							//!< \brief Returns x * (1.0 - a) + y * a, i.e., the linear blend of x and y using the floating-point value a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T, P> lerp(const detail::tvec2<T, P>& x, const detail::tvec2<T, P>& y, const detail::tvec2<T, P>& a){return mix(x, y, a);}	//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T, P> lerp(const detail::tvec3<T, P>& x, const detail::tvec3<T, P>& y, const detail::tvec3<T, P>& a){return mix(x, y, a);}	//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T, P> lerp(const detail::tvec4<T, P>& x, const detail::tvec4<T, P>& y, const detail::tvec4<T, P>& a){return mix(x, y, a);}	//!< \brief Returns the component-wise result of x * (1.0 - a) + y * a, i.e., the linear blend of x and y using vector a. The value for a is not restricted to the range [0, 1]. (From GLM_GTX_compatibility)
 
-	template <typename T> GLM_FUNC_QUALIFIER T slerp(detail::tquat<T> const & x, detail::tquat<T> const & y, T const & a){return mix(x, y, a);} //!< \brief Returns the slurp interpolation between two quaternions.
+	template <typename T> GLM_FUNC_QUALIFIER T slerp(detail::tquat<T, P> const & x, detail::tquat<T, P> const & y, T const & a){return mix(x, y, a);} //!< \brief Returns the slurp interpolation between two quaternions.
 
 	template <typename T> GLM_FUNC_QUALIFIER T saturate(T x){return clamp(x, T(0), T(1));}														//!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T> saturate(const detail::tvec2<T>& x){return clamp(x, T(0), T(1));}					//!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T> saturate(const detail::tvec3<T>& x){return clamp(x, T(0), T(1));}					//!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T> saturate(const detail::tvec4<T>& x){return clamp(x, T(0), T(1));}					//!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T, P> saturate(const detail::tvec2<T, P>& x){return clamp(x, T(0), T(1));}					//!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T, P> saturate(const detail::tvec3<T, P>& x){return clamp(x, T(0), T(1));}					//!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T, P> saturate(const detail::tvec4<T, P>& x){return clamp(x, T(0), T(1));}					//!< \brief Returns clamp(x, 0, 1) for each component in x. (From GLM_GTX_compatibility)
 
 	template <typename T> GLM_FUNC_QUALIFIER T atan2(T x, T y){return atan(x, y);}																//!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T> atan2(const detail::tvec2<T>& x, const detail::tvec2<T>& y){return atan(x, y);}	//!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T> atan2(const detail::tvec3<T>& x, const detail::tvec3<T>& y){return atan(x, y);}	//!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
-	template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T> atan2(const detail::tvec4<T>& x, const detail::tvec4<T>& y){return atan(x, y);}	//!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec2<T, P> atan2(const detail::tvec2<T, P>& x, const detail::tvec2<T, P>& y){return atan(x, y);}	//!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec3<T, P> atan2(const detail::tvec3<T, P>& x, const detail::tvec3<T, P>& y){return atan(x, y);}	//!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
+	template <typename T> GLM_FUNC_QUALIFIER detail::tvec4<T, P> atan2(const detail::tvec4<T, P>& x, const detail::tvec4<T, P>& y){return atan(x, y);}	//!< \brief Arc tangent. Returns an angle whose tangent is y/x. The signs of x and y are used to determine what quadrant the angle is in. The range of values returned by this function is [-PI, PI]. Results are undefined if x and y are both 0. (From GLM_GTX_compatibility)
 
 	template <typename genType> bool isfinite(genType const & x);											//!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)
 	template <typename valType> detail::tvec2<bool> isfinite(const detail::tvec2<valType>& x);				//!< \brief Test whether or not a scalar or each vector component is a finite value. (From GLM_GTX_compatibility)

+ 186 - 101
glm/gtx/dual_quaternion.hpp

@@ -54,88 +54,88 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
+	template <typename T, precision P>
 	struct tdualquat// : public genType<T, tquat>
 	{
 		enum ctor{null};
 		
 		typedef T value_type;
-		typedef glm::detail::tquat<T> part_type;
+		typedef glm::detail::tquat<T, P> part_type;
 		typedef std::size_t size_type;
 		
 	public:
-		glm::detail::tquat<T> real, dual;
+		glm::detail::tquat<T, P> real, dual;
 		
 		GLM_FUNC_DECL size_type length() const;
 		
 		// Constructors
 		tdualquat();
-		explicit tdualquat(tquat<T> const & real);
-		tdualquat(tquat<T> const & real,tquat<T> const & dual);
-		tdualquat(tquat<T> const & orientation,tvec3<T> const& translation);
+		explicit tdualquat(tquat<T, P> const & real);
+		tdualquat(tquat<T, P> const & real,tquat<T, P> const & dual);
+		tdualquat(tquat<T, P> const & orientation,tvec3<T, P> const& translation);
 		
 		//////////////////////////////////////////////////////////////
 		// tdualquat conversions
-		explicit tdualquat(tmat2x4<T> const & holder_mat);
-		explicit tdualquat(tmat3x4<T> const & aug_mat);
+		explicit tdualquat(tmat2x4<T, P> const & holder_mat);
+		explicit tdualquat(tmat3x4<T, P> const & aug_mat);
 		
 		// Accesses
 		part_type & operator[](int i);
 		part_type const & operator[](int i) const;
 		
 		// Operators
-		tdualquat<T> & operator*=(value_type const & s);
-		tdualquat<T> & operator/=(value_type const & s);
+		tdualquat<T, P> & operator*=(value_type const & s);
+		tdualquat<T, P> & operator/=(value_type const & s);
 	};
 	
-	template <typename T>
-	detail::tquat<T> operator- (
-		detail::tquat<T> const & q);
-	
-	template <typename T>
-	detail::tdualquat<T> operator+ (
-		detail::tdualquat<T> const & q,
-		detail::tdualquat<T> const & p);
-	
-	template <typename T>
-	detail::tdualquat<T> operator* (
-		detail::tdualquat<T> const & q,
-		detail::tdualquat<T> const & p);
-	
-	template <typename T>
-	detail::tvec3<T> operator* (
-		detail::tquat<T> const & q,
-		detail::tvec3<T> const & v);
-	
-	template <typename T>
-	detail::tvec3<T> operator* (
-		detail::tvec3<T> const & v,
-		detail::tquat<T> const & q);
-	
-	template <typename T>
-	detail::tvec4<T> operator* (
-		detail::tquat<T> const & q,
-		detail::tvec4<T> const & v);
-	
-	template <typename T>
-	detail::tvec4<T> operator* (
-		detail::tvec4<T> const & v,
-		detail::tquat<T> const & q);
-	
-	template <typename T>
-	detail::tdualquat<T> operator* (
-		detail::tdualquat<T> const & q,
-		typename detail::tdualquat<T>::value_type const & s);
-	
-	template <typename T>
-	detail::tdualquat<T> operator* (
-		typename detail::tdualquat<T>::value_type const & s,
-		detail::tdualquat<T> const & q);
-	
-	template <typename T>
-	detail::tdualquat<T> operator/ (
-		detail::tdualquat<T> const & q,
-		typename detail::tdualquat<T>::value_type const & s);
+	template <typename T, precision P>
+	detail::tquat<T, P> operator- (
+		detail::tquat<T, P> const & q);
+	
+	template <typename T, precision P>
+	detail::tdualquat<T, P> operator+ (
+		detail::tdualquat<T, P> const & q,
+		detail::tdualquat<T, P> const & p);
+	
+	template <typename T, precision P>
+	detail::tdualquat<T, P> operator* (
+		detail::tdualquat<T, P> const & q,
+		detail::tdualquat<T, P> const & p);
+	
+	template <typename T, precision P>
+	detail::tvec3<T, P> operator* (
+		detail::tquat<T, P> const & q,
+		detail::tvec3<T, P> const & v);
+	
+	template <typename T, precision P>
+	detail::tvec3<T, P> operator* (
+		detail::tvec3<T, P> const & v,
+		detail::tquat<T, P> const & q);
+	
+	template <typename T, precision P>
+	detail::tvec4<T, P> operator* (
+		detail::tquat<T, P> const & q,
+		detail::tvec4<T, P> const & v);
+	
+	template <typename T, precision P>
+	detail::tvec4<T, P> operator* (
+		detail::tvec4<T, P> const & v,
+		detail::tquat<T, P> const & q);
+	
+	template <typename T, precision P>
+	detail::tdualquat<T, P> operator* (
+		detail::tdualquat<T, P> const & q,
+		typename detail::tdualquat<T, P>::value_type const & s);
+	
+	template <typename T, precision P>
+	detail::tdualquat<T, P> operator* (
+		typename detail::tdualquat<T, P>::value_type const & s,
+		detail::tdualquat<T, P> const & q);
+	
+	template <typename T, precision P>
+	detail::tdualquat<T, P> operator/ (
+		detail::tdualquat<T, P> const & q,
+		typename detail::tdualquat<T, P>::value_type const & s);
 } //namespace detail
 	
 	/// @addtogroup gtc_dual_quaternion
@@ -144,98 +144,183 @@ namespace detail
 	/// Returns the normalized quaternion.
 	///
 	/// @see gtc_dual_quaternion
-	template <typename T>
-	detail::tdualquat<T> normalize(
-		detail::tdualquat<T> const & q);
+	template <typename T, precision P>
+	detail::tdualquat<T, P> normalize(
+		detail::tdualquat<T, P> const & q);
 
 	/// Returns the linear interpolation of two dual quaternion.
 	///
 	/// @see gtc_dual_quaternion
-	template <typename T>
-	detail::tdualquat<T> lerp (
-		detail::tdualquat<T> const & x,
-		detail::tdualquat<T> const & y,
-		typename detail::tdualquat<T>::value_type const & a);
+	template <typename T, precision P>
+	detail::tdualquat<T, P> lerp(
+		detail::tdualquat<T, P> const & x,
+		detail::tdualquat<T, P> const & y,
+		typename detail::tdualquat<T, P>::value_type const & a);
 
 	/// Returns the q inverse.
 	///
 	/// @see gtc_dual_quaternion
-	template <typename T>
-	detail::tdualquat<T> inverse(
-		detail::tdualquat<T> const & q);
+	template <typename T, precision P>
+	detail::tdualquat<T, P> inverse(
+		detail::tdualquat<T, P> const & q);
 
 	/*
 	/// Extracts a rotation part from dual-quaternion to a 3 * 3 matrix.
 	/// TODO
 	///
 	/// @see gtc_dual_quaternion
-	template <typename T>
-	detail::tmat3x3<T> mat3_cast(
-		detail::tdualquat<T> const & x);
+	template <typename T, precision P>
+	detail::tmat3x3<T, P> mat3_cast(
+		detail::tdualquat<T, P> const & x);
 	*/
 	
 	/// Converts a quaternion to a 2 * 4 matrix.
 	///
 	/// @see gtc_dual_quaternion
-	template <typename T>
-	detail::tmat2x4<T> mat2x4_cast(
-		detail::tdualquat<T> const & x);
+	template <typename T, precision P>
+	detail::tmat2x4<T, P> mat2x4_cast(
+		detail::tdualquat<T, P> const & x);
 
 	/// Converts a quaternion to a 3 * 4 matrix.
 	///
 	/// @see gtc_dual_quaternion
-	template <typename T>
-	detail::tmat3x4<T> mat3x4_cast(
-		detail::tdualquat<T> const & x);
+	template <typename T, precision P>
+	detail::tmat3x4<T, P> mat3x4_cast(
+		detail::tdualquat<T, P> const & x);
 
 	/// Converts a 2 * 4 matrix (matrix which holds real and dual parts) to a quaternion.
 	///
 	/// @see gtc_dual_quaternion
-	template <typename T>
-	detail::tdualquat<T> dualquat_cast(
-		detail::tmat2x4<T> const & x);
+	template <typename T, precision P>
+	detail::tdualquat<T, P> dualquat_cast(
+		detail::tmat2x4<T, P> const & x);
 
 	/// Converts a 3 * 4 matrix (augmented matrix rotation + translation) to a quaternion.
 	///
 	/// @see gtc_dual_quaternion
-	template <typename T>
-	detail::tdualquat<T> dualquat_cast(
-		detail::tmat3x4<T> const & x);
+	template <typename T, precision P>
+	detail::tdualquat<T, P> dualquat_cast(
+		detail::tmat3x4<T, P> const & x);
 
-	/// Dual-quaternion of floating-point numbers.
+
+	/// Dual-quaternion of low half-precision floating-point numbers.
 	///
 	/// @see gtc_dual_quaternion
-	typedef detail::tdualquat<float> dualquat;
-
-	/// Dual-quaternion of half-precision floating-point numbers.
+	typedef detail::tdualquat<half, lowp>		lowp_hdualquat;
+	
+	/// Dual-quaternion of medium half-precision floating-point numbers.
 	///
 	/// @see gtc_dual_quaternion
-	typedef detail::tdualquat<detail::half>	hdualquat;
-
-	/// Dual-quaternion of single-precision floating-point numbers.
+	typedef detail::tdualquat<half, mediump>	mediump_hdualquat;
+	
+	/// Dual-quaternion of high half-precision floating-point numbers.
 	///
 	/// @see gtc_dual_quaternion
-	typedef detail::tdualquat<float>	fdualquat;
-
-	/// Dual-quaternion of double-precision floating-point numbers.
+	typedef detail::tdualquat<half, highp>		highp_hdualquat;
+	
+	
+	/// Dual-quaternion of low single-precision floating-point numbers.
+	///
+	/// @see gtc_dual_quaternion
+	typedef detail::tdualquat<float, lowp>		lowp_dualquat;
+	
+	/// Dual-quaternion of medium single-precision floating-point numbers.
+	///
+	/// @see gtc_dual_quaternion
+	typedef detail::tdualquat<float, mediump>	mediump_dualquat;
+	
+	/// Dual-quaternion of high single-precision floating-point numbers.
 	///
 	/// @see gtc_dual_quaternion
-	typedef detail::tdualquat<double>	ddualquat;
+	typedef detail::tdualquat<float, highp>		highp_dualquat;
 
-	/// Dual-quaternion of low precision floating-point numbers.
+
+	/// Dual-quaternion of low single-precision floating-point numbers.
+	///
+	/// @see gtc_dual_quaternion
+	typedef detail::tdualquat<float, lowp>		lowp_fdualquat;
+	
+	/// Dual-quaternion of medium single-precision floating-point numbers.
+	///
+	/// @see gtc_dual_quaternion
+	typedef detail::tdualquat<float, mediump>	mediump_fdualquat;
+	
+	/// Dual-quaternion of high single-precision floating-point numbers.
+	///
+	/// @see gtc_dual_quaternion
+	typedef detail::tdualquat<float, highp>		highp_fdualquat;
+	
+	
+	/// Dual-quaternion of low double-precision floating-point numbers.
+	///
+	/// @see gtc_dual_quaternion
+	typedef detail::tdualquat<double, lowp>		lowp_ddualquat;
+	
+	/// Dual-quaternion of medium double-precision floating-point numbers.
+	///
+	/// @see gtc_dual_quaternion
+	typedef detail::tdualquat<double, mediump>	mediump_ddualquat;
+	
+	/// Dual-quaternion of high double-precision floating-point numbers.
 	///
 	/// @see gtc_dual_quaternion
-	typedef detail::tdualquat<lowp_float>		lowp_dualquat;
+	typedef detail::tdualquat<double, highp>	highp_ddualquat;
 
-	/// Dual-quaternion of medium precision floating-point numbers.
+	
+#if(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
+	/// Dual-quaternion of floating-point numbers.
+	///
+	/// @see gtc_dual_quaternion
+	typedef mediump_fdualquat		dualquat;
+	
+	/// Dual-quaternion of single-precision floating-point numbers.
+	///
+	/// @see gtc_dual_quaternion
+	typedef mediump_fdualquat		fdualquat;
+#elif(defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
+	typedef highp_fdualquat			dualquat;
+	typedef highp_fdualquat			fdualquat;
+#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && defined(GLM_PRECISION_MEDIUMP_FLOAT) && !defined(GLM_PRECISION_LOWP_FLOAT))
+	typedef mediump_fdualquat		dualquat;
+	typedef mediump_fdualquat		fdualquat;
+#elif(!defined(GLM_PRECISION_HIGHP_FLOAT) && !defined(GLM_PRECISION_MEDIUMP_FLOAT) && defined(GLM_PRECISION_LOWP_FLOAT))
+	typedef lowp_fdualquat			dualquat;
+	typedef lowp_fdualquat			fdualquat;
+#else
+#	error "GLM error: multiple default precision requested for single-precision floating-point types"
+#endif
+	
+	
+#if(!defined(GLM_PRECISION_HIGHP_HALF) && !defined(GLM_PRECISION_MEDIUMP_HALF) && !defined(GLM_PRECISION_LOWP_HALF))
+	/// Dual-quaternion of default half-precision floating-point numbers.
 	///
 	/// @see gtc_dual_quaternion
-	typedef detail::tdualquat<mediump_float>	mediump_dualquat;
+	typedef mediump_hdualquat		hdualquat;
+#elif(defined(GLM_PRECISION_HIGHP_HALF) && !defined(GLM_PRECISION_MEDIUMP_HALF) && !defined(GLM_PRECISION_LOWP_HALF))
+	typedef highp_hdualquat			hdualquat;
+#elif(!defined(GLM_PRECISION_HIGHP_HALF) && defined(GLM_PRECISION_MEDIUMP_HALF) && !defined(GLM_PRECISION_LOWP_HALF))
+	typedef mediump_hdualquat		hdualquat;
+#elif(!defined(GLM_PRECISION_HIGHP_HALF) && !defined(GLM_PRECISION_MEDIUMP_HALF) && defined(GLM_PRECISION_LOWP_HALF))
+	typedef lowp_hdualquat			hdualquat;
+#else
+#	error "GLM error: Multiple default precision requested for half-precision floating-point types"
+#endif
+
 
-	/// Dual-quaternion of high precision floating-point numbers.
+#if(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
+	/// Dual-quaternion of default double-precision floating-point numbers.
 	///
 	/// @see gtc_dual_quaternion
-	typedef detail::tdualquat<highp_float>		highp_dualquat;
+	typedef mediump_ddualquat		ddualquat;
+#elif(defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
+	typedef highp_ddualquat			ddualquat;
+#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && defined(GLM_PRECISION_MEDIUMP_DOUBLE) && !defined(GLM_PRECISION_LOWP_DOUBLE))
+	typedef mediump_ddualquat		ddualquat;
+#elif(!defined(GLM_PRECISION_HIGHP_DOUBLE) && !defined(GLM_PRECISION_MEDIUMP_DOUBLE) && defined(GLM_PRECISION_LOWP_DOUBLE))
+	typedef lowp_ddualquat			ddualquat;
+#else
+#	error "GLM error: Multiple default precision requested for double-precision floating-point types"
+#endif
 
 	/// @}
 } //namespace glm

+ 137 - 137
glm/gtx/dual_quaternion.inl

@@ -31,42 +31,42 @@
 namespace glm{
 namespace detail
 {
-	template <typename T>
-	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tdualquat<T>::size_type tdualquat<T>::length() const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER GLM_CONSTEXPR typename tdualquat<T, P>::size_type tdualquat<T, P>::length() const
 	{
 		return 8;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tdualquat<T>::tdualquat() :
-		real(tquat<T>()),
-		dual(tquat<T>(T(0), T(0), T(0), T(0)))
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tdualquat<T, P>::tdualquat() :
+		real(tquat<T, P>()),
+		dual(tquat<T, P>(T(0), T(0), T(0), T(0)))
 	{}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tdualquat<T>::tdualquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tdualquat<T, P>::tdualquat
 	(
-		tquat<T> const & r
+		tquat<T, P> const & r
 	) :
 		real(r),
-		dual(tquat<T>(T(0), T(0), T(0), T(0)))
+		dual(tquat<T, P>(T(0), T(0), T(0), T(0)))
 	{}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tdualquat<T>::tdualquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tdualquat<T, P>::tdualquat
 	(
-		tquat<T> const & r,
-		tquat<T> const & d
+		tquat<T, P> const & r,
+		tquat<T, P> const & d
 	) :
 		real(r),
 		dual(d)
 	{}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tdualquat<T>::tdualquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tdualquat<T, P>::tdualquat
 	(
-		tquat<T> const & q,
-		tvec3<T> const& p
+		tquat<T, P> const & q,
+		tvec3<T, P> const& p
 	) :
 		real(q),
 		dual(
@@ -78,35 +78,35 @@ namespace detail
 
 	//////////////////////////////////////////////////////////////
 	// tdualquat conversions
-	template <typename T>
-	GLM_FUNC_QUALIFIER tdualquat<T>::tdualquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tdualquat<T, P>::tdualquat
 	(
-		tmat2x4<T> const & m
+		tmat2x4<T, P> const & m
 	)
 	{
 		*this = dualquat_cast(m);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tdualquat<T>::tdualquat
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tdualquat<T, P>::tdualquat
 	(
-		tmat3x4<T> const & m
+		tmat3x4<T, P> const & m
 	)
 	{
 		*this = dualquat_cast(m);
 	}
 
 	//////////////////////////////////////////////////////////////
-	// tdualquat<T> accesses
+	// tdualquat<T, P> accesses
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tdualquat<T>::part_type & tdualquat<T>::operator [] (int i)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tdualquat<T, P>::part_type & tdualquat<T, P>::operator [] (int i)
 	{
 		return (&real)[i];
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER typename tdualquat<T>::part_type const & tdualquat<T>::operator [] (int i) const
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER typename tdualquat<T, P>::part_type const & tdualquat<T, P>::operator [] (int i) const
 	{
 		return (&real)[i];
 	}
@@ -114,8 +114,8 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// tdualquat<valType> operators
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tdualquat<T> & tdualquat<T>::operator *=
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tdualquat<T, P> & tdualquat<T, P>::operator *=
 	(
 		value_type const & s
 	)
@@ -125,8 +125,8 @@ namespace detail
 		return *this;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER tdualquat<T> & tdualquat<T>::operator /=
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER tdualquat<T, P> & tdualquat<T, P>::operator /=
 	(
 		value_type const & s
 	)
@@ -139,125 +139,125 @@ namespace detail
 	//////////////////////////////////////////////////////////////
 	// tquat<valType> external operators
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> operator-
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> operator-
 	(
-		detail::tdualquat<T> const & q
+		detail::tdualquat<T, P> const & q
 	)
 	{
-		return detail::tdualquat<T>(-q.real,-q.dual);
+		return detail::tdualquat<T, P>(-q.real,-q.dual);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> operator+
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> operator+
 	(
-		detail::tdualquat<T> const & q,
-		detail::tdualquat<T> const & p
+		detail::tdualquat<T, P> const & q,
+		detail::tdualquat<T, P> const & p
 	)
 	{
-		return detail::tdualquat<T>(q.real + p.real,q.dual + p.dual);
+		return detail::tdualquat<T, P>(q.real + p.real,q.dual + p.dual);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> operator*
 	(
-		detail::tdualquat<T> const & p,
-		detail::tdualquat<T> const & o
+		detail::tdualquat<T, P> const & p,
+		detail::tdualquat<T, P> const & o
 	)
 	{
-		return detail::tdualquat<T>(p.real * o.real,p.real * o.dual + p.dual * o.real);
+		return detail::tdualquat<T, P>(p.real * o.real,p.real * o.dual + p.dual * o.real);
 	}
 
 	// Transformation
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> operator*
 	(
-		detail::tdualquat<T> const & q,
-		detail::tvec3<T> const & v
+		detail::tdualquat<T, P> const & q,
+		detail::tvec3<T, P> const & v
 	)
 	{
-		detail::tvec3<T> const real_v3(q.real.x,q.real.y,q.real.z);
-		detail::tvec3<T> const dual_v3(q.dual.x,q.dual.y,q.dual.z);
+		detail::tvec3<T, P> const real_v3(q.real.x,q.real.y,q.real.z);
+		detail::tvec3<T, P> const dual_v3(q.dual.x,q.dual.y,q.dual.z);
 		return (cross(real_v3, cross(real_v3,v) + v * q.real.w + dual_v3) + dual_v3 * q.real.w - real_v3 * q.dual.w) * T(2) + v;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> operator*
 	(
-		detail::tvec3<T> const & v,
-		detail::tdualquat<T> const & q
+		detail::tvec3<T, P> const & v,
+		detail::tdualquat<T, P> const & q
 	)
 	{
 		return inverse(q) * v;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> operator*
 	(
-		detail::tdualquat<T> const & q,
-		detail::tvec4<T> const & v
+		detail::tdualquat<T, P> const & q,
+		detail::tvec4<T, P> const & v
 	)
 	{
-		return detail::tvec4<T>(q * detail::tvec3<T>(v), v.w);
+		return detail::tvec4<T, P>(q * detail::tvec3<T, P>(v), v.w);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> operator*
 	(
-		detail::tvec4<T> const & v,
-		detail::tdualquat<T> const & q
+		detail::tvec4<T, P> const & v,
+		detail::tdualquat<T, P> const & q
 	)
 	{
 		return inverse(q) * v;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> operator*
 	(
-		detail::tdualquat<T> const & q,
-		typename detail::tdualquat<T>::value_type const & s
+		detail::tdualquat<T, P> const & q,
+		typename detail::tdualquat<T, P>::value_type const & s
 	)
 	{
-		return detail::tdualquat<T>(q.real * s, q.dual * s);
+		return detail::tdualquat<T, P>(q.real * s, q.dual * s);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> operator*
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> operator*
 	(
-		typename detail::tdualquat<T>::value_type const & s,
-		detail::tdualquat<T> const & q
+		typename detail::tdualquat<T, P>::value_type const & s,
+		detail::tdualquat<T, P> const & q
 	)
 	{
 		return q * s;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> operator/
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> operator/
 	(
-		detail::tdualquat<T> const & q,
-		typename detail::tdualquat<T>::value_type const & s
+		detail::tdualquat<T, P> const & q,
+		typename detail::tdualquat<T, P>::value_type const & s
 	)
 	{
-		return detail::tdualquat<T>(q.real / s, q.dual / s);
+		return detail::tdualquat<T, P>(q.real / s, q.dual / s);
 	}
 
 	//////////////////////////////////////
 	// Boolean operators
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator==
 	(
-		detail::tdualquat<T> const & q1,
-		detail::tdualquat<T> const & q2
+		detail::tdualquat<T, P> const & q1,
+		detail::tdualquat<T, P> const & q2
 	)
 	{
 		return (q1.real == q2.real) && (q1.dual == q2.dual);
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER bool operator!=
 	(
-		detail::tdualquat<T> const & q1,
-		detail::tdualquat<T> const & q2
+		detail::tdualquat<T, P> const & q1,
+		detail::tdualquat<T, P> const & q2
 	)
 	{
 		return (q1.real != q2.dual) || (q1.real != q2.dual);
@@ -265,69 +265,69 @@ namespace detail
 	}//namespace detail
 
 	////////////////////////////////////////////////////////
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> normalize
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> normalize
 	(
-		detail::tdualquat<T> const & q
+		detail::tdualquat<T, P> const & q
 	)
 	{
 		return q / length(q.real);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> lerp
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> lerp
 	(
-		detail::tdualquat<T> const & x,
-		detail::tdualquat<T> const & y,
-		typename detail::tdualquat<T>::value_type const & a
+		detail::tdualquat<T, P> const & x,
+		detail::tdualquat<T, P> const & y,
+		typename detail::tdualquat<T, P>::value_type const & a
 	)
 	{
 		// Dual Quaternion Linear blend aka DLB:
 		// Lerp is only defined in [0, 1]
 		assert(a >= T(0));
 		assert(a <= T(1));
-		T const k = dot(x.real,y.real) < detail::tdualquat<T>::value_type(0) ? -a : a;
+		T const k = dot(x.real,y.real) < detail::tdualquat<T, P>::value_type(0) ? -a : a;
 		T const one(1);
-		return detail::tdualquat<T>(x * (one - a) + y * k);
+		return detail::tdualquat<T, P>(x * (one - a) + y * k);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> inverse
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> inverse
 	(
-		detail::tdualquat<T> const & q
+		detail::tdualquat<T, P> const & q
 	)
 	{
-		const glm::detail::tquat<T> real = conjugate(q.real);
-		const glm::detail::tquat<T> dual = conjugate(q.dual);
-		return detail::tdualquat<T>(real, dual + (real * (-2.0f * dot(real,dual))));
+		const glm::detail::tquat<T, P> real = conjugate(q.real);
+		const glm::detail::tquat<T, P> dual = conjugate(q.dual);
+		return detail::tdualquat<T, P>(real, dual + (real * (-2.0f * dot(real,dual))));
 	}
 	/*
-	 template <typename T>
-	 GLM_FUNC_QUALIFIER detail::tmat3x3<T> mat3_cast
+	 template <typename T, precision P>
+	 GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> mat3_cast
 	 (
-	 detail::tdualquat<T> const & x
+	 detail::tdualquat<T, P> const & x
 	 )
 	 {
 	 }
 	 */
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat2x4<T> mat2x4_cast
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat2x4<T, P> mat2x4_cast
 	(
-		detail::tdualquat<T> const & x
+		detail::tdualquat<T, P> const & x
 	)
 	{
-		return detail::tmat2x4<T>( x[0].x, x[0].y, x[0].z, x[0].w, x[1].x, x[1].y, x[1].z, x[1].w );
+		return detail::tmat2x4<T, P>( x[0].x, x[0].y, x[0].z, x[0].w, x[1].x, x[1].y, x[1].z, x[1].w );
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x4<T> mat3x4_cast
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x4<T, P> mat3x4_cast
 	(
-		detail::tdualquat<T> const & x
+		detail::tdualquat<T, P> const & x
 	)
 	{
-		detail::tquat<T> r = x.real / length2(x.real);
+		detail::tquat<T, P> r = x.real / length2(x.real);
 		
-		detail::tquat<T> const rr(r.w * x.real.w, r.x * x.real.x, r.y * x.real.y, r.z * x.real.z);
+		detail::tquat<T, P> const rr(r.w * x.real.w, r.x * x.real.x, r.y * x.real.y, r.z * x.real.z);
 		r *= T(2);
 		
 		T const xy = r.x * x.real.y;
@@ -337,61 +337,61 @@ namespace detail
 		T const wy = r.w * x.real.y;
 		T const wz = r.w * x.real.z;
 		
-		detail::tvec4<T> const a(
+		detail::tvec4<T, P> const a(
 			rr.w + rr.x - rr.y - rr.z,
 			xy - wz,
 			xz + wy,
 			-(x.dual.w * r.x - x.dual.x * r.w + x.dual.y * r.z - x.dual.z * r.y));
 		
-		detail::tvec4<T> const b(
+		detail::tvec4<T, P> const b(
 			xy + wz,
 			rr.w + rr.y - rr.x - rr.z,
 			yz - wx,
 			-(x.dual.w * r.y - x.dual.x * r.z - x.dual.y * r.w + x.dual.z * r.x));
 		
-		detail::tvec4<T> const c(
+		detail::tvec4<T, P> const c(
 			xz - wy,
 			yz + wx,
 			rr.w + rr.z - rr.x - rr.y,
 			-(x.dual.w * r.z + x.dual.x * r.y - x.dual.y * r.x - x.dual.z * r.w));
 		
-		return detail::tmat3x4<T>(a, b, c);
+		return detail::tmat3x4<T, P>(a, b, c);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> dualquat_cast
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> dualquat_cast
 	(
-		detail::tmat2x4<T> const & x
+		detail::tmat2x4<T, P> const & x
 	)
 	{
-		return detail::tdualquat<T>(
-			detail::tquat<T>( x[0].w, x[0].x, x[0].y, x[0].z ),
-			detail::tquat<T>( x[1].w, x[1].x, x[1].y, x[1].z ));
+		return detail::tdualquat<T, P>(
+			detail::tquat<T, P>( x[0].w, x[0].x, x[0].y, x[0].z ),
+			detail::tquat<T, P>( x[1].w, x[1].x, x[1].y, x[1].z ));
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tdualquat<T> dualquat_cast
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tdualquat<T, P> dualquat_cast
 	(
-		detail::tmat3x4<T> const & x
+		detail::tmat3x4<T, P> const & x
 	)
 	{
-		detail::tquat<T> real;
+		detail::tquat<T, P> real;
 		
 		T const trace = x[0].x + x[1].y + x[2].z;
-		if(trace > detail::tdualquat<T>::value_type(0))
+		if(trace > detail::tdualquat<T, P>::value_type(0))
 		{
-			T const r = sqrt(detail::tdualquat<T>::value_type(1) + trace);
-			T const invr = detail::tdualquat<T>::value_type(0.5) / r;
-			real.w = detail::tdualquat<T>::value_type(0.5) * r;
+			T const r = sqrt(detail::tdualquat<T, P>::value_type(1) + trace);
+			T const invr = detail::tdualquat<T, P>::value_type(0.5) / r;
+			real.w = detail::tdualquat<T, P>::value_type(0.5) * r;
 			real.x = (x[2].y - x[1].z) * invr;
 			real.y = (x[0].z - x[2].x) * invr;
 			real.z = (x[1].x - x[0].y) * invr;
 		}
 		else if(x[0].x > x[1].y && x[0].x > x[2].z)
 		{
-			T const r = sqrt(detail::tdualquat<T>::value_type(1) + x[0].x - x[1].y - x[2].z);
-			T const invr = detail::tdualquat<T>::value_type(0.5) / r;
-			real.x = detail::tdualquat<T>::value_type(0.5)*r;
+			T const r = sqrt(detail::tdualquat<T, P>::value_type(1) + x[0].x - x[1].y - x[2].z);
+			T const invr = detail::tdualquat<T, P>::value_type(0.5) / r;
+			real.x = detail::tdualquat<T, P>::value_type(0.5)*r;
 			real.y = (x[1].x + x[0].y) * invr;
 			real.z = (x[0].z + x[2].x) * invr;
 			real.w = (x[2].y - x[1].z) * invr;
@@ -415,12 +415,12 @@ namespace detail
 			real.w = (x[1].x - x[0].y) * invr;
 		}
 		
-		detail::tquat<T> dual;
+		detail::tquat<T, P> dual;
 		dual.x =  T(0.5) * ( x[0].w * real.w + x[1].w * real.z - x[2].w * real.y);
 		dual.y =  T(0.5) * (-x[0].w * real.z + x[1].w * real.w + x[2].w * real.x);
 		dual.z =  T(0.5) * ( x[0].w * real.y - x[1].w * real.x + x[2].w * real.w);
 		dual.w = -T(0.5) * ( x[0].w * real.x + x[1].w * real.y + x[2].w * real.z);
-		return detail::tdualquat<T>(real, dual);
+		return detail::tdualquat<T, P>(real, dual);
 	}
 
 }//namespace glm

+ 51 - 51
glm/gtx/euler_angles.hpp

@@ -54,99 +54,99 @@ namespace glm
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle X.
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleX(
-		valType const & angleX);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleX(
+		T const & angleX);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Y.
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleY(
-		valType const & angleY);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleY(
+		T const & angleY);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from an euler angle Z.
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleZ(
-		valType const & angleZ);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleZ(
+		T const & angleZ);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Y).
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleXY(
-		valType const & angleX, 
-		valType const & angleY);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleXY(
+		T const & angleX,
+		T const & angleY);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X).
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleYX(
-		valType const & angleY, 
-		valType const & angleX);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleYX(
+		T const & angleY,
+		T const & angleX);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (X * Z).
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleXZ(
-		valType const & angleX, 
-		valType const & angleZ);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleXZ(
+		T const & angleX,
+		T const & angleZ);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * X).
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleZX(
-		valType const & angleZ, 
-		valType const & angleX);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleZX(
+		T const & angle,
+		T const & angleX);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * Z).
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleYZ(
-		valType const & angleY, 
-		valType const & angleZ);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleYZ(
+		T const & angleY,
+		T const & angleZ);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Z * Y).
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleZY(
-		valType const & angleZ, 
-		valType const & angleY);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleZY(
+		T const & angleZ,
+		T const & angleY);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z).
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> eulerAngleYXZ(
-		valType const & yaw, 
-		valType const & pitch, 
-		valType const & roll);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> eulerAngleYXZ(
+		T const & yaw,
+		T const & pitch,
+		T const & roll);
 
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z).
 	/// @see gtx_euler_angles
-	template <typename valType> 
-	detail::tmat4x4<valType> yawPitchRoll(
-		valType const & yaw, 
-		valType const & pitch, 
-		valType const & roll);
+	template <typename T>
+	detail::tmat4x4<T, defaultp> yawPitchRoll(
+		T const & yaw,
+		T const & pitch,
+		T const & roll);
 
 	/// Creates a 2D 2 * 2 rotation matrix from an euler angle.
 	/// @see gtx_euler_angles
-	template <typename T> 
-	detail::tmat2x2<T> orientate2(T const & angle);
+	template <typename T>
+	detail::tmat2x2<T, defaultp> orientate2(T const & angle);
 
 	/// Creates a 2D 4 * 4 homogeneous rotation matrix from an euler angle.
 	/// @see gtx_euler_angles
-	template <typename T> 
-	detail::tmat3x3<T> orientate3(T const & angle);
+	template <typename T>
+	detail::tmat3x3<T, defaultp> orientate3(T const & angle);
 
 	/// Creates a 3D 3 * 3 rotation matrix from euler angles (Y * X * Z). 
 	/// @see gtx_euler_angles
-	template <typename T> 
-	detail::tmat3x3<T> orientate3(detail::tvec3<T> const & angles);
+	template <typename T, precision P>
+	detail::tmat3x3<T, P> orientate3(detail::tvec3<T, P> const & angles);
 		
 	/// Creates a 3D 4 * 4 homogeneous rotation matrix from euler angles (Y * X * Z).
 	/// @see gtx_euler_angles
-	template <typename T> 
-	detail::tmat4x4<T> orientate4(detail::tvec3<T> const & angles);
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> orientate4(detail::tvec3<T, P> const & angles);
 
 	/// @}
 }//namespace glm

+ 127 - 127
glm/gtx/euler_angles.inl

@@ -9,192 +9,192 @@
 
 namespace glm
 {
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleX
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> eulerAngleX
 	(
-		valType const & angleX
+		T const & angleX
 	)
 	{
-		valType cosX = glm::cos(angleX);
-		valType sinX = glm::sin(angleX);
+		T cosX = glm::cos(angleX);
+		T sinX = glm::sin(angleX);
 	
-		return detail::tmat4x4<valType>(
-			valType(1), valType(0), valType(0), valType(0),
-			valType(0), cosX,		sinX,		valType(0),
-			valType(0),-sinX,		cosX,		valType(0),
-			valType(0), valType(0), valType(0), valType(1));
+		return detail::tmat4x4<T, defaultp>(
+			T(1), T(0), T(0), T(0),
+			T(0), cosX, sinX, T(0),
+			T(0),-sinX, cosX, T(0),
+			T(0), T(0), T(0), T(1));
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleY
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> eulerAngleY
 	(
-		valType const & angleY
+		T const & angleY
 	)
 	{
-		valType cosY = glm::cos(angleY);
-		valType sinY = glm::sin(angleY);
-
-		return detail::tmat4x4<valType>(
-			cosY,		valType(0),	sinY,		valType(0),
-			valType(0),	valType(1),	valType(0), valType(0),
-			-sinY,		valType(0),	cosY,		valType(0),
-			valType(0),	valType(0),	valType(0), valType(1));
+		T cosY = glm::cos(angleY);
+		T sinY = glm::sin(angleY);
+
+		return detail::tmat4x4<T, defaultp>(
+			cosY,	T(0),	sinY,	T(0),
+			T(0),	T(1),	T(0),	T(0),
+			-sinY,	T(0),	cosY,	T(0),
+			T(0),	T(0),	T(0),	T(1));
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleZ
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> eulerAngleZ
 	(
-		valType const & angleZ
+		T const & angleZ
 	)
 	{
-		valType cosZ = glm::cos(angleZ); 
-		valType sinZ = glm::sin(angleZ);
-
-		return detail::tmat4x4<valType>(
-			cosZ,		sinZ,		valType(0), valType(0),
-			-sinZ,		cosZ,		valType(0), valType(0),
-			valType(0),	valType(0),	valType(1), valType(0),
-			valType(0),	valType(0),	valType(0), valType(1));
+		T cosZ = glm::cos(angleZ);
+		T sinZ = glm::sin(angleZ);
+
+		return detail::tmat4x4<T, defaultp>(
+			cosZ,	sinZ,	T(0), T(0),
+			-sinZ,	cosZ,	T(0), T(0),
+			T(0),	T(0),	T(1), T(0),
+			T(0),	T(0),	T(0), T(1));
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleXY
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> eulerAngleXY
 	(
-		valType const & angleX, 
-		valType const & angleY
+		T const & angleX,
+		T const & angleY
 	)
 	{
-		valType cosX = glm::cos(angleX);
-		valType sinX = glm::sin(angleX);
-		valType cosY = glm::cos(angleY);
-		valType sinY = glm::sin(angleY);
-
-		return detail::tmat4x4<valType>(
-			cosY,		-sinX * sinY,	cosX * sinY,	valType(0),
-			valType(0), cosX,			sinX,			valType(0),
-			-sinY ,		-sinX * cosY,	cosX * cosY,	valType(0),
-			valType(0), valType(0),     valType(0),		valType(1));
+		T cosX = glm::cos(angleX);
+		T sinX = glm::sin(angleX);
+		T cosY = glm::cos(angleY);
+		T sinY = glm::sin(angleY);
+
+		return detail::tmat4x4<T, defaultp>(
+			cosY,	-sinX * sinY,	cosX * sinY,	T(0),
+			T(0),	cosX,			sinX,			T(0),
+			-sinY,	-sinX * cosY,	cosX * cosY,	T(0),
+			T(0),	T(0),			T(0),			T(1));
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleYX
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> eulerAngleYX
 	(
-		valType const & angleY, 
-		valType const & angleX
+		T const & angleY,
+		T const & angleX
 	)
 	{
-		valType cosX = glm::cos(angleX); 
-		valType sinX = glm::sin(angleX); 
-		valType cosY = glm::cos(angleY); 
-		valType sinY = glm::sin(angleY);
-
-		return detail::tmat4x4<valType>(
-			cosY,			valType(0),		sinY,			valType(0),
-			-sinX * sinY,	cosX,			sinX * cosY,	valType(0),
-			-cosX * sinY,	-sinX,			cosX * cosY,	valType(0),
-			valType(0),		valType(0),		valType(0),		valType(1));
+		T cosX = glm::cos(angleX);
+		T sinX = glm::sin(angleX);
+		T cosY = glm::cos(angleY);
+		T sinY = glm::sin(angleY);
+
+		return detail::tmat4x4<T, defaultp>(
+			cosY,			T(0),		sinY,			T(0),
+			-sinX * sinY,	cosX,		sinX * cosY,	T(0),
+			-cosX * sinY,	-sinX,		cosX * cosY,	T(0),
+			T(0),			T(0),		T(0),			T(1));
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleXZ
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> eulerAngleXZ
 	(
-		valType const & angleX, 
-		valType const & angleZ
+		T const & angleX,
+		T const & angleZ
 	)
 	{
 		return eulerAngleX(angleX) * eulerAngleZ(angleZ);
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleZX
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> eulerAngleZX
 	(
-		valType const & angleZ, 
-		valType const & angleX
+		T const & angleZ,
+		T const & angleX
 	)
 	{
 		return eulerAngleZ(angleZ) * eulerAngleX(angleX);
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> eulerAngleYXZ
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> eulerAngleYXZ
 	(
-		valType const & yaw, 
-		valType const & pitch, 
-		valType const & roll
+		T const & yaw,
+		T const & pitch,
+		T const & roll
 	)
 	{
-		valType tmp_ch = glm::cos(yaw);
-		valType tmp_sh = glm::sin(yaw);
-		valType tmp_cp = glm::cos(pitch);
-		valType tmp_sp = glm::sin(pitch);
-		valType tmp_cb = glm::cos(roll);
-		valType tmp_sb = glm::sin(roll);
-
-		detail::tmat4x4<valType> Result;
+		T tmp_ch = glm::cos(yaw);
+		T tmp_sh = glm::sin(yaw);
+		T tmp_cp = glm::cos(pitch);
+		T tmp_sp = glm::sin(pitch);
+		T tmp_cb = glm::cos(roll);
+		T tmp_sb = glm::sin(roll);
+
+		detail::tmat4x4<T, defaultp> Result;
 		Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
 		Result[0][1] = tmp_sb * tmp_cp;
 		Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
-		Result[0][3] = valType(0);
+		Result[0][3] = T(0);
 		Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
 		Result[1][1] = tmp_cb * tmp_cp;
 		Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
-		Result[1][3] = valType(0);
+		Result[1][3] = T(0);
 		Result[2][0] = tmp_sh * tmp_cp;
 		Result[2][1] = -tmp_sp;
 		Result[2][2] = tmp_ch * tmp_cp;
-		Result[2][3] = valType(0);
-		Result[3][0] = valType(0);
-		Result[3][1] = valType(0);
-		Result[3][2] = valType(0);
-		Result[3][3] = valType(1);
+		Result[2][3] = T(0);
+		Result[3][0] = T(0);
+		Result[3][1] = T(0);
+		Result[3][2] = T(0);
+		Result[3][3] = T(1);
 		return Result;
 	}
 
-	template <typename valType> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> yawPitchRoll
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, defaultp> yawPitchRoll
 	(
-		valType const & yaw, 
-		valType const & pitch, 
-		valType const & roll
+		T const & yaw,
+		T const & pitch,
+		T const & roll
 	)
 	{
-		valType tmp_ch = glm::cos(yaw);
-		valType tmp_sh = glm::sin(yaw);
-		valType tmp_cp = glm::cos(pitch);
-		valType tmp_sp = glm::sin(pitch);
-		valType tmp_cb = glm::cos(roll);
-		valType tmp_sb = glm::sin(roll);
-
-		detail::tmat4x4<valType> Result;
+		T tmp_ch = glm::cos(yaw);
+		T tmp_sh = glm::sin(yaw);
+		T tmp_cp = glm::cos(pitch);
+		T tmp_sp = glm::sin(pitch);
+		T tmp_cb = glm::cos(roll);
+		T tmp_sb = glm::sin(roll);
+
+		detail::tmat4x4<T, defaultp> Result;
 		Result[0][0] = tmp_ch * tmp_cb + tmp_sh * tmp_sp * tmp_sb;
 		Result[0][1] = tmp_sb * tmp_cp;
 		Result[0][2] = -tmp_sh * tmp_cb + tmp_ch * tmp_sp * tmp_sb;
-		Result[0][3] = valType(0);
+		Result[0][3] = T(0);
 		Result[1][0] = -tmp_ch * tmp_sb + tmp_sh * tmp_sp * tmp_cb;
 		Result[1][1] = tmp_cb * tmp_cp;
 		Result[1][2] = tmp_sb * tmp_sh + tmp_ch * tmp_sp * tmp_cb;
-		Result[1][3] = valType(0);
+		Result[1][3] = T(0);
 		Result[2][0] = tmp_sh * tmp_cp;
 		Result[2][1] = -tmp_sp;
 		Result[2][2] = tmp_ch * tmp_cp;
-		Result[2][3] = valType(0);
-		Result[3][0] = valType(0);
-		Result[3][1] = valType(0);
-		Result[3][2] = valType(0);
-		Result[3][3] = valType(1);
+		Result[2][3] = T(0);
+		Result[3][0] = T(0);
+		Result[3][1] = T(0);
+		Result[3][2] = T(0);
+		Result[3][3] = T(1);
 		return Result;
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tmat2x2<valType> orientate2
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, defaultp> orientate2
 	(
-		valType const & angle
+		T const & angle
 	)
 	{
-		valType c = glm::cos(angle);
-		valType s = glm::sin(angle);
+		T c = glm::cos(angle);
+		T s = glm::sin(angle);
 
-		detail::tmat2x2<valType> Result;
+		detail::tmat2x2<T, defaultp> Result;
 		Result[0][0] = c;
 		Result[0][1] = s;
 		Result[1][0] = -s;
@@ -202,16 +202,16 @@ namespace glm
 		return Result;
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<valType> orientate3
+	template <typename T>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, defaultp> orientate3
 	(
-		valType const & angle
+		T const & angle
 	)
 	{
-		valType c = glm::cos(angle);
-		valType s = glm::sin(angle);
+		T c = glm::cos(angle);
+		T s = glm::sin(angle);
 
-		detail::tmat3x3<valType> Result;
+		detail::tmat3x3<T, defaultp> Result;
 		Result[0][0] = c;
 		Result[0][1] = s;
 		Result[0][2] = 0.0f;
@@ -224,19 +224,19 @@ namespace glm
 		return Result;
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<valType> orientate3
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> orientate3
 	(
-		detail::tvec3<valType> const & angles
+		detail::tvec3<T, P> const & angles
 	)
 	{
-		return detail::tmat3x3<valType>(yawPitchRoll(angles.x, angles.y, angles.z));
+		return detail::tmat3x3<T, P>(yawPitchRoll(angles.x, angles.y, angles.z));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<valType> orientate4
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> orientate4
 	(
-		detail::tvec3<valType> const & angles
+		detail::tvec3<T, P> const & angles
 	)
 	{
 		return yawPitchRoll(angles.z, angles.x, angles.y);

+ 9 - 9
glm/gtx/fast_exponential.inl

@@ -28,32 +28,32 @@ namespace glm
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec2<T> fastPow(
-		const detail::tvec2<T>& x, 
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> fastPow(
+		const detail::tvec2<T, P>& x, 
 		const detail::tvec2<int>& y)
 	{
-		return detail::tvec2<T>(
+		return detail::tvec2<T, P>(
 			fastPow(x.x, y.x),
 			fastPow(x.y, y.y));
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec3<T> fastPow(
-		const detail::tvec3<T>& x, 
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> fastPow(
+		const detail::tvec3<T, P>& x, 
 		const detail::tvec3<int>& y)
 	{
-		return detail::tvec3<T>(
+		return detail::tvec3<T, P>(
 			fastPow(x.x, y.x),
 			fastPow(x.y, y.y),
 			fastPow(x.z, y.z));
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tvec4<T> fastPow(
-		const detail::tvec4<T>& x, 
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> fastPow(
+		const detail::tvec4<T, P>& x, 
 		const detail::tvec4<int>& y)
 	{
-		return detail::tvec4<T>(
+		return detail::tvec4<T, P>(
 			fastPow(x.x, y.x),
 			fastPow(x.y, y.y),
 			fastPow(x.z, y.z),

+ 11 - 11
glm/gtx/gradient_paint.hpp

@@ -53,20 +53,20 @@ namespace glm
 
 	/// Return a color from a radial gradient.
 	/// @see - gtx_gradient_paint
-	template <typename valType>
-	valType radialGradient(
-		detail::tvec2<valType> const & Center,
-		valType const & Radius,
-		detail::tvec2<valType> const & Focal,
-		detail::tvec2<valType> const & Position);
+	template <typename T, precision P>
+	T radialGradient(
+		detail::tvec2<T, P> const & Center,
+		T const & Radius,
+		detail::tvec2<T, P> const & Focal,
+		detail::tvec2<T, P> const & Position);
 
 	/// Return a color from a linear gradient.
 	/// @see - gtx_gradient_paint
-	template <typename valType>
-	valType linearGradient(
-		detail::tvec2<valType> const & Point0,
-		detail::tvec2<valType> const & Point1,
-		detail::tvec2<valType> const & Position);
+	template <typename T, precision P>
+	T linearGradient(
+		detail::tvec2<T, P> const & Point0,
+		detail::tvec2<T, P> const & Point1,
+		detail::tvec2<T, P> const & Position);
 
 	/// @}
 }// namespace glm

+ 20 - 20
glm/gtx/gradient_paint.inl

@@ -2,42 +2,42 @@
 // OpenGL Mathematics Copyright (c) 2005 - 2013 G-Truc Creation (www.g-truc.net)
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 // Created : 2009-03-06
-// Updated : 2009-03-09
+// Updated : 2013-04-09
 // Licence : This source is under MIT License
 // File    : glm/gtx/gradient_paint.inl
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 namespace glm
 {
-	template <typename valType>
-	valType radialGradient
+	template <typename T, precision P>
+	T radialGradient
 	(
-		detail::tvec2<valType> const & Center,
-		valType const & Radius,
-		detail::tvec2<valType> const & Focal,
-		detail::tvec2<valType> const & Position
+		detail::tvec2<T, P> const & Center,
+		T const & Radius,
+		detail::tvec2<T, P> const & Focal,
+		detail::tvec2<T, P> const & Position
 	)
 	{
-		detail::tvec2<valType> F = Focal - Center;
-		detail::tvec2<valType> D = Position - Focal;
-		valType Radius2 = pow2(Radius);
-		valType Fx2 = pow2(F.x);
-		valType Fy2 = pow2(F.y);
+		detail::tvec2<T, P> F = Focal - Center;
+		detail::tvec2<T, P> D = Position - Focal;
+		T Radius2 = pow2(Radius);
+		T Fx2 = pow2(F.x);
+		T Fy2 = pow2(F.y);
 
-		valType Numerator = (D.x * F.x + D.y * F.y) + sqrt(Radius2 * (pow2(D.x) + pow2(D.y)) - pow2(D.x * F.y - D.y * F.x));
-		valType Denominator = Radius2 - (Fx2 + Fy2);
+		T Numerator = (D.x * F.x + D.y * F.y) + sqrt(Radius2 * (pow2(D.x) + pow2(D.y)) - pow2(D.x * F.y - D.y * F.x));
+		T Denominator = Radius2 - (Fx2 + Fy2);
 		return Numerator / Denominator;
 	}
 
-	template <typename valType>
-	valType linearGradient
+	template <typename T, precision P>
+	T linearGradient
 	(
-		detail::tvec2<valType> const & Point0,
-		detail::tvec2<valType> const & Point1,
-		detail::tvec2<valType> const & Position
+		detail::tvec2<T, P> const & Point0,
+		detail::tvec2<T, P> const & Point1,
+		detail::tvec2<T, P> const & Position
 	)
 	{
-		detail::tvec2<valType> Dist = Point1 - Point0;
+		detail::tvec2<T, P> Dist = Point1 - Point0;
 		return (Dist.x * (Position.x - Point0.x) + Dist.y * (Position.y - Point0.y)) / glm::dot(Dist, Dist);
 	}
 }//namespace glm

+ 6 - 6
glm/gtx/handed_coordinate_space.hpp

@@ -54,17 +54,17 @@ namespace glm
 	//! From GLM_GTX_handed_coordinate_space extension.
 	template <typename T> 
 	bool rightHanded(
-		detail::tvec3<T> const & tangent, 
-		detail::tvec3<T> const & binormal, 
-		detail::tvec3<T> const & normal);
+		detail::tvec3<T, P> const & tangent, 
+		detail::tvec3<T, P> const & binormal, 
+		detail::tvec3<T, P> const & normal);
 
 	//! Return if a trihedron left handed or not.
 	//! From GLM_GTX_handed_coordinate_space extension.
 	template <typename T> 
 	bool leftHanded(
-		detail::tvec3<T> const & tangent, 
-		detail::tvec3<T> const & binormal, 
-		detail::tvec3<T> const & normal);
+		detail::tvec3<T, P> const & tangent, 
+		detail::tvec3<T, P> const & binormal, 
+		detail::tvec3<T, P> const & normal);
 
 	/// @}
 }// namespace glm

+ 6 - 6
glm/gtx/handed_coordinate_space.inl

@@ -12,9 +12,9 @@ namespace glm
 	template <typename T> 
 	GLM_FUNC_QUALIFIER bool rightHanded
 	(
-		detail::tvec3<T> const & tangent, 
-		detail::tvec3<T> const & binormal,
-		detail::tvec3<T> const & normal
+		detail::tvec3<T, P> const & tangent, 
+		detail::tvec3<T, P> const & binormal,
+		detail::tvec3<T, P> const & normal
 	)
 	{
 		return dot(cross(normal, tangent), binormal) > T(0);
@@ -23,9 +23,9 @@ namespace glm
 	template <typename T> 
 	GLM_FUNC_QUALIFIER bool leftHanded
 	(
-		detail::tvec3<T> const & tangent, 
-		detail::tvec3<T> const & binormal, 
-		detail::tvec3<T> const & normal
+		detail::tvec3<T, P> const & tangent, 
+		detail::tvec3<T, P> const & binormal, 
+		detail::tvec3<T, P> const & normal
 	)
 	{
 		return dot(cross(normal, tangent), binormal) < T(0);

+ 10 - 10
glm/gtx/inertia.hpp

@@ -54,56 +54,56 @@ namespace glm
 	//! Build an inertia matrix for a box.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
-	detail::tmat3x3<T> boxInertia3(
+	detail::tmat3x3<T, P> boxInertia3(
 		T const & Mass, 
-		detail::tvec3<T> const & Scale);
+		detail::tvec3<T, P> const & Scale);
 		
 	//! Build an inertia matrix for a box.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
-	detail::tmat4x4<T> boxInertia4(
+	detail::tmat4x4<T, P> boxInertia4(
 		T const & Mass, 
-		detail::tvec3<T> const & Scale);
+		detail::tvec3<T, P> const & Scale);
 		
 	//! Build an inertia matrix for a disk.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
-	detail::tmat3x3<T> diskInertia3(
+	detail::tmat3x3<T, P> diskInertia3(
 		T const & Mass, 
 		T const & Radius);
 
 	//! Build an inertia matrix for a disk.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
-	detail::tmat4x4<T> diskInertia4(
+	detail::tmat4x4<T, P> diskInertia4(
 		T const & Mass, 
 		T const & Radius);
 
 	//! Build an inertia matrix for a ball.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
-	detail::tmat3x3<T> ballInertia3(
+	detail::tmat3x3<T, P> ballInertia3(
 		T const & Mass, 
 		T const & Radius);
 		
 	//! Build an inertia matrix for a ball.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
-	detail::tmat4x4<T> ballInertia4(
+	detail::tmat4x4<T, P> ballInertia4(
 		T const & Mass, 
 		T const & Radius);
 
 	//! Build an inertia matrix for a sphere.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
-	detail::tmat3x3<T> sphereInertia3(
+	detail::tmat3x3<T, P> sphereInertia3(
 		T const & Mass, 
 		T const & Radius);
 
 	//! Build an inertia matrix for a sphere.
 	//! From GLM_GTX_inertia extension.
 	template <typename T> 
-	detail::tmat4x4<T> sphereInertia4(
+	detail::tmat4x4<T, P> sphereInertia4(
 		T const & Mass, 
 		T const & Radius);
 

+ 18 - 18
glm/gtx/inertia.inl

@@ -10,13 +10,13 @@
 namespace glm
 {
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> boxInertia3
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> boxInertia3
 	(
 		T const & Mass, 
-		detail::tvec3<T> const & Scale
+		detail::tvec3<T, P> const & Scale
 	)
 	{
-		detail::tmat3x3<T> Result(T(1));
+		detail::tmat3x3<T, P> Result(T(1));
 		Result[0][0] = (Scale.y * Scale.y + Scale.z * Scale.z) * Mass / T(12);
 		Result[1][1] = (Scale.x * Scale.x + Scale.z * Scale.z) * Mass / T(12);
 		Result[2][2] = (Scale.x * Scale.x + Scale.y * Scale.y) * Mass / T(12);
@@ -24,13 +24,13 @@ namespace glm
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> boxInertia4
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> boxInertia4
 	(
 		T const & Mass, 
-		detail::tvec3<T> const & Scale
+		detail::tvec3<T, P> const & Scale
 	)
 	{
-		detail::tmat4x4<T> Result(T(1));
+		detail::tmat4x4<T, P> Result(T(1));
 		Result[0][0] = (Scale.y * Scale.y + Scale.z * Scale.z) * Mass / T(12);
 		Result[1][1] = (Scale.x * Scale.x + Scale.z * Scale.z) * Mass / T(12);
 		Result[2][2] = (Scale.x * Scale.x + Scale.y * Scale.y) * Mass / T(12);
@@ -38,76 +38,76 @@ namespace glm
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> diskInertia3
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> diskInertia3
 	(
 		T const & Mass, 
 		T const & Radius
 	)
 	{
 		T a = Mass * Radius * Radius / T(2);
-		detail::tmat3x3<T> Result(a);
+		detail::tmat3x3<T, P> Result(a);
 		Result[2][2] *= T(2);
 		return Result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> diskInertia4
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> diskInertia4
 	(
 		T const & Mass, 
 		T const & Radius
 	)
 	{
 		T a = Mass * Radius * Radius / T(2);
-		detail::tmat4x4<T> Result(a);
+		detail::tmat4x4<T, P> Result(a);
 		Result[2][2] *= T(2);
 		Result[3][3] = T(1);
 		return Result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> ballInertia3
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> ballInertia3
 	(
 		T const & Mass, 
 		T const & Radius
 	)
 	{
 		T a = T(2) * Mass * Radius * Radius / T(5);
-		return detail::tmat3x3<T>(a);
+		return detail::tmat3x3<T, P>(a);
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> ballInertia4
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> ballInertia4
 	(
 		T const & Mass, 
 		T const & Radius
 	)
 	{
 		T a = T(2) * Mass * Radius * Radius / T(5);
-		detail::tmat4x4<T> Result(a);
+		detail::tmat4x4<T, P> Result(a);
 		Result[3][3] = T(1);
 		return Result;
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> sphereInertia3
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> sphereInertia3
 	(
 		T const & Mass, 
 		T const & Radius
 	)
 	{
 		T a = T(2) * Mass * Radius * Radius / T(3);
-		return detail::tmat3x3<T>(a);
+		return detail::tmat3x3<T, P>(a);
 	}
 
 	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> sphereInertia4
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> sphereInertia4
 	(
 		T const & Mass, 
 		T const & Radius
 	)
 	{
 		T a = T(2) * Mass * Radius * Radius / T(3);
-		detail::tmat4x4<T> Result(a);
+		detail::tmat4x4<T, P> Result(a);
 		Result[3][3] = T(1);
 		return Result;
 	}

+ 12 - 12
glm/gtx/integer.inl

@@ -100,30 +100,30 @@ namespace _detail
 		return Result;
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec2<valType> factorial(
-		detail::tvec2<valType> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<T, P> factorial(
+		detail::tvec2<T, P> const & x)
 	{
-		return detail::tvec2<valType>(
+		return detail::tvec2<T, P>(
 			factorial(x.x),
 			factorial(x.y));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec3<valType> factorial(
-		detail::tvec3<valType> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> factorial(
+		detail::tvec3<T, P> const & x)
 	{
-		return detail::tvec3<valType>(
+		return detail::tvec3<T, P>(
 			factorial(x.x),
 			factorial(x.y),
 			factorial(x.z));
 	}
 
-	template <typename valType>
-	GLM_FUNC_QUALIFIER detail::tvec4<valType> factorial(
-		detail::tvec4<valType> const & x)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<T, P> factorial(
+		detail::tvec4<T, P> const & x)
 	{
-		return detail::tvec4<valType>(
+		return detail::tvec4<T, P>(
 			factorial(x.x),
 			factorial(x.y),
 			factorial(x.z),

+ 4 - 4
glm/gtx/matrix_cross_product.hpp

@@ -54,14 +54,14 @@ namespace glm
 	//! Build a cross product matrix.
 	//! From GLM_GTX_matrix_cross_product extension.
 	template <typename T> 
-	detail::tmat3x3<T> matrixCross3(
-		detail::tvec3<T> const & x);
+	detail::tmat3x3<T, P> matrixCross3(
+		detail::tvec3<T, P> const & x);
 		
 	//! Build a cross product matrix.
 	//! From GLM_GTX_matrix_cross_product extension.
 	template <typename T> 
-	detail::tmat4x4<T> matrixCross4(
-		detail::tvec3<T> const & x);
+	detail::tmat4x4<T, P> matrixCross4(
+		detail::tvec3<T, P> const & x);
 
 	/// @}
 }//namespace glm

+ 6 - 6
glm/gtx/matrix_cross_product.inl

@@ -10,12 +10,12 @@
 namespace glm
 {
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> matrixCross3
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> matrixCross3
 	(
-		detail::tvec3<T> const & x
+		detail::tvec3<T, P> const & x
 	)
 	{
-		detail::tmat3x3<T> Result(T(0));
+		detail::tmat3x3<T, P> Result(T(0));
 		Result[0][1] = x.z;
 		Result[1][0] = -x.z;
 		Result[0][2] = -x.y;
@@ -26,12 +26,12 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> matrixCross4
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> matrixCross4
 	(
-		detail::tvec3<T> const & x
+		detail::tvec3<T, P> const & x
 	)
 	{
-		detail::tmat4x4<T> Result(T(0));
+		detail::tmat4x4<T, P> Result(T(0));
 		Result[0][1] = x.z;
 		Result[1][0] = -x.z;
 		Result[0][2] = -x.y;

+ 26 - 26
glm/gtx/matrix_interpolation.hpp

@@ -50,35 +50,35 @@ namespace glm
 	/// @addtogroup gtx_matrix_interpolation
 	/// @{
 
-	//! Get the axis and angle of the rotation from a matrix.
-    //! From GLM_GTX_matrix_interpolation extension.
-	template <typename T>
-    void axisAngle(
-        detail::tmat4x4<T> const & mat,
-        detail::tvec3<T> & axis,
-        T & angle);
+	/// Get the axis and angle of the rotation from a matrix.
+	/// From GLM_GTX_matrix_interpolation extension.
+	template <typename T, precision P>
+	void axisAngle(
+		detail::tmat4x4<T, P> const & mat,
+		detail::tvec3<T, P> & axis,
+		T & angle);
 
-    //! Build a matrix from axis and angle.
-    //! From GLM_GTX_matrix_interpolation extension.
-	template <typename T>
-    detail::tmat4x4<T> axisAngleMatrix(
-        detail::tvec3<T> const & axis,
-        T const angle);
+	/// Build a matrix from axis and angle.
+	/// From GLM_GTX_matrix_interpolation extension.
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> axisAngleMatrix(
+		detail::tvec3<T, P> const & axis,
+		T const angle);
 
-	//! Extracts the rotation part of a matrix.
-    //! From GLM_GTX_matrix_interpolation extension.
-	template <typename T>
-	detail::tmat4x4<T> extractMatrixRotation(
-		detail::tmat4x4<T> const & mat);
+	/// Extracts the rotation part of a matrix.
+	/// From GLM_GTX_matrix_interpolation extension.
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> extractMatrixRotation(
+		detail::tmat4x4<T, P> const & mat);
 
-	//! Build a interpolation of 4 * 4 matrixes.
-    //! From GLM_GTX_matrix_interpolation extension.
-    //! Warning! works only with rotation and/or translation matrixes, scale will generate unexpected results.
-	template <typename T>
-    detail::tmat4x4<T> interpolate(
-        detail::tmat4x4<T> const & m1,
-        detail::tmat4x4<T> const & m2,
-        T const delta);
+	/// Build a interpolation of 4 * 4 matrixes.
+	/// From GLM_GTX_matrix_interpolation extension.
+	/// Warning! works only with rotation and/or translation matrixes, scale will generate unexpected results.
+	template <typename T, precision P>
+	detail::tmat4x4<T, P> interpolate(
+		detail::tmat4x4<T, P> const & m1,
+		detail::tmat4x4<T, P> const & m2,
+		T const delta);
 
 	/// @}
 }//namespace glm

+ 34 - 25
glm/gtx/matrix_interpolation.inl

@@ -9,19 +9,21 @@
 
 namespace glm
 {
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER void axisAngle
 	(
-		detail::tmat4x4<T> const & mat,
-		detail::tvec3<T> & axis,
+		detail::tmat4x4<T, P> const & mat,
+		detail::tvec3<T, P> & axis,
 		T & angle
 	)
 	{
 		T epsilon = (T)0.01;
 		T epsilon2 = (T)0.1;
 
-		if ((fabs(mat[1][0] - mat[0][1]) < epsilon) && (fabs(mat[2][0] - mat[0][2]) < epsilon) && (fabs(mat[2][1] - mat[1][2]) < epsilon)) {
-			if ((fabs(mat[1][0] + mat[0][1]) < epsilon2) && (fabs(mat[2][0] + mat[0][2]) < epsilon2) && (fabs(mat[2][1] + mat[1][2]) < epsilon2) && (fabs(mat[0][0] + mat[1][1] + mat[2][2] - (T)3.0) < epsilon2)) {
+		if((abs(mat[1][0] - mat[0][1]) < epsilon) && (abs(mat[2][0] - mat[0][2]) < epsilon) && (abs(mat[2][1] - mat[1][2]) < epsilon))
+		{
+			if ((abs(mat[1][0] + mat[0][1]) < epsilon2) && (abs(mat[2][0] + mat[0][2]) < epsilon2) && (abs(mat[2][1] + mat[1][2]) < epsilon2) && (abs(mat[0][0] + mat[1][1] + mat[2][2] - (T)3.0) < epsilon2))
+			{
 				angle = (T)0.0;
 				axis.x = (T)1.0;
 				axis.y = (T)0.0;
@@ -35,7 +37,8 @@ namespace glm
 			T xy = (mat[1][0] + mat[0][1]) / (T)4.0;
 			T xz = (mat[2][0] + mat[0][2]) / (T)4.0;
 			T yz = (mat[2][1] + mat[1][2]) / (T)4.0;
-			if ((xx > yy) && (xx > zz)) {
+			if((xx > yy) && (xx > zz))
+			{
 				if (xx < epsilon) {
 					axis.x = (T)0.0;
 					axis.y = (T)0.7071;
@@ -45,7 +48,9 @@ namespace glm
 					axis.y = xy / axis.x;
 					axis.z = xz / axis.x;
 				}
-			} else if (yy > zz) {
+			}
+			else if (yy > zz)
+			{
 				if (yy < epsilon) {
 					axis.x = (T)0.7071;
 					axis.y = (T)0.0;
@@ -55,7 +60,9 @@ namespace glm
 					axis.x = xy / axis.y;
 					axis.z = yz / axis.y;
 				}
-			} else {
+			}
+			else
+			{
 				if (zz < epsilon) {
 					axis.x = (T)0.7071;
 					axis.y = (T)0.7071;
@@ -77,19 +84,19 @@ namespace glm
 		axis.z = (mat[0][1] - mat[1][0]) / s;
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> axisAngleMatrix
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> axisAngleMatrix
 	(
-		detail::tvec3<T> const & axis,
+		detail::tvec3<T, P> const & axis,
 		T const angle
 	)
 	{
 		T c = cos(angle);
 		T s = sin(angle);
 		T t = T(1) - c;
-		detail::tvec3<T> n = normalize(axis);
+		detail::tvec3<T, P> n = normalize(axis);
 
-		return detail::tmat4x4<T>(
+		return detail::tmat4x4<T, P>(
 			t * n.x * n.x + c,          t * n.x * n.y + n.z * s,    t * n.x * n.z - n.y * s,    T(0),
 			t * n.x * n.y - n.z * s,    t * n.y * n.y + c,          t * n.y * n.z + n.x * s,    T(0),
 			t * n.x * n.z + n.y * s,    t * n.y * n.z - n.x * s,    t * n.z * n.z + c,          T(0),
@@ -97,11 +104,13 @@ namespace glm
 		);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> extractMatrixRotation(
-		detail::tmat4x4<T> const & mat)
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> extractMatrixRotation
+	(
+		detail::tmat4x4<T, P> const & mat
+	)
 	{
-		return detail::tmat4x4<T>(
+		return detail::tmat4x4<T, P>(
 			mat[0][0], mat[0][1], mat[0][2], 0.0,
 			mat[1][0], mat[1][1], mat[1][2], 0.0,
 			mat[2][0], mat[2][1], mat[2][2], 0.0,
@@ -109,20 +118,20 @@ namespace glm
 		);
 	}
 
-	template <typename T>
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> interpolate
+	template <typename T, precision P>
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> interpolate
 	(
-		detail::tmat4x4<T> const & m1,
-		detail::tmat4x4<T> const & m2,
+		detail::tmat4x4<T, P> const & m1,
+		detail::tmat4x4<T, P> const & m2,
 		T const delta
 	)
 	{
-		detail::tmat4x4<T> m1rot = extractMatrixRotation(m1);
-		detail::tmat4x4<T> dltRotation = m2 * transpose(m1rot);
-		detail::tvec3<T> dltAxis;
+		detail::tmat4x4<T, P> m1rot = extractMatrixRotation(m1);
+		detail::tmat4x4<T, P> dltRotation = m2 * transpose(m1rot);
+		detail::tvec3<T, P> dltAxis;
 		T dltAngle;
 		axisAngle(dltRotation, dltAxis, dltAngle);
-		detail::tmat4x4<T> out = axisAngleMatrix(dltAxis, dltAngle * delta) * m1rot;
+		detail::tmat4x4<T, P> out = axisAngleMatrix(dltAxis, dltAngle * delta) * m1rot;
 		out[3][0] = m1[3][0] + delta * (m2[3][0] - m1[3][0]);
 		out[3][1] = m1[3][1] + delta * (m2[3][1] - m1[3][1]);
 		out[3][2] = m1[3][2] + delta * (m2[3][2] - m1[3][2]);

+ 36 - 36
glm/gtx/matrix_major_storage.hpp

@@ -54,86 +54,86 @@ namespace glm
 	//! Build a row major matrix from row vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat2x2<T> rowMajor2(
-		detail::tvec2<T> const & v1, 
-		detail::tvec2<T> const & v2);
+	detail::tmat2x2<T, P> rowMajor2(
+		detail::tvec2<T, P> const & v1, 
+		detail::tvec2<T, P> const & v2);
 		
 	//! Build a row major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat2x2<T> rowMajor2(
-		detail::tmat2x2<T> const & m);
+	detail::tmat2x2<T, P> rowMajor2(
+		detail::tmat2x2<T, P> const & m);
 
 	//! Build a row major matrix from row vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat3x3<T> rowMajor3(
-		detail::tvec3<T> const & v1, 
-		detail::tvec3<T> const & v2, 
-		detail::tvec3<T> const & v3);
+	detail::tmat3x3<T, P> rowMajor3(
+		detail::tvec3<T, P> const & v1, 
+		detail::tvec3<T, P> const & v2, 
+		detail::tvec3<T, P> const & v3);
 
 	//! Build a row major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat3x3<T> rowMajor3(
-		detail::tmat3x3<T> const & m);
+	detail::tmat3x3<T, P> rowMajor3(
+		detail::tmat3x3<T, P> const & m);
 
 	//! Build a row major matrix from row vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat4x4<T> rowMajor4(
-		detail::tvec4<T> const & v1, 
-		detail::tvec4<T> const & v2,
-		detail::tvec4<T> const & v3, 
-		detail::tvec4<T> const & v4);
+	detail::tmat4x4<T, P> rowMajor4(
+		detail::tvec4<T, P> const & v1, 
+		detail::tvec4<T, P> const & v2,
+		detail::tvec4<T, P> const & v3, 
+		detail::tvec4<T, P> const & v4);
 
 	//! Build a row major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat4x4<T> rowMajor4(
-		detail::tmat4x4<T> const & m);
+	detail::tmat4x4<T, P> rowMajor4(
+		detail::tmat4x4<T, P> const & m);
 
 	//! Build a column major matrix from column vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat2x2<T> colMajor2(
-		detail::tvec2<T> const & v1, 
-		detail::tvec2<T> const & v2);
+	detail::tmat2x2<T, P> colMajor2(
+		detail::tvec2<T, P> const & v1, 
+		detail::tvec2<T, P> const & v2);
 		
 	//! Build a column major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat2x2<T> colMajor2(
-		detail::tmat2x2<T> const & m);
+	detail::tmat2x2<T, P> colMajor2(
+		detail::tmat2x2<T, P> const & m);
 
 	//! Build a column major matrix from column vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat3x3<T> colMajor3(
-		detail::tvec3<T> const & v1, 
-		detail::tvec3<T> const & v2, 
-		detail::tvec3<T> const & v3);
+	detail::tmat3x3<T, P> colMajor3(
+		detail::tvec3<T, P> const & v1, 
+		detail::tvec3<T, P> const & v2, 
+		detail::tvec3<T, P> const & v3);
 		
 	//! Build a column major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat3x3<T> colMajor3(
-		detail::tmat3x3<T> const & m);
+	detail::tmat3x3<T, P> colMajor3(
+		detail::tmat3x3<T, P> const & m);
 		
 	//! Build a column major matrix from column vectors.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat4x4<T> colMajor4(
-		detail::tvec4<T> const & v1, 
-		detail::tvec4<T> const & v2, 
-		detail::tvec4<T> const & v3, 
-		detail::tvec4<T> const & v4);
+	detail::tmat4x4<T, P> colMajor4(
+		detail::tvec4<T, P> const & v1, 
+		detail::tvec4<T, P> const & v2, 
+		detail::tvec4<T, P> const & v3, 
+		detail::tvec4<T, P> const & v4);
 				
 	//! Build a column major matrix from other matrix.
 	//! From GLM_GTX_matrix_major_storage extension.
 	template <typename T> 
-	detail::tmat4x4<T> colMajor4(
-		detail::tmat4x4<T> const & m);
+	detail::tmat4x4<T, P> colMajor4(
+		detail::tmat4x4<T, P> const & m);
 
 	/// @}
 }//namespace glm

+ 48 - 48
glm/gtx/matrix_major_storage.inl

@@ -10,13 +10,13 @@
 namespace glm
 {
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat2x2<T> rowMajor2
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, P> rowMajor2
 	(
-		detail::tvec2<T> const & v1, 
-		detail::tvec2<T> const & v2
+		detail::tvec2<T, P> const & v1, 
+		detail::tvec2<T, P> const & v2
 	)
 	{
-		detail::tmat2x2<T> Result;
+		detail::tmat2x2<T, P> Result;
 		Result[0][0] = v1.x;
 		Result[1][0] = v1.y;
 		Result[0][1] = v2.x;
@@ -25,10 +25,10 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat2x2<T> rowMajor2(
-		const detail::tmat2x2<T>& m)
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, P> rowMajor2(
+		const detail::tmat2x2<T, P>& m)
 	{
-		detail::tmat2x2<T> Result;
+		detail::tmat2x2<T, P> Result;
 		Result[0][0] = m[0][0];
 		Result[0][1] = m[1][0];
 		Result[1][0] = m[0][1];
@@ -37,12 +37,12 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> rowMajor3(
-		const detail::tvec3<T>& v1, 
-		const detail::tvec3<T>& v2, 
-		const detail::tvec3<T>& v3)
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> rowMajor3(
+		const detail::tvec3<T, P>& v1, 
+		const detail::tvec3<T, P>& v2, 
+		const detail::tvec3<T, P>& v3)
 	{
-		detail::tmat3x3<T> Result;
+		detail::tmat3x3<T, P> Result;
 		Result[0][0] = v1.x;
 		Result[1][0] = v1.y;
 		Result[2][0] = v1.z;
@@ -56,10 +56,10 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> rowMajor3(
-		const detail::tmat3x3<T>& m)
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> rowMajor3(
+		const detail::tmat3x3<T, P>& m)
 	{
-		detail::tmat3x3<T> Result;
+		detail::tmat3x3<T, P> Result;
 		Result[0][0] = m[0][0];
 		Result[0][1] = m[1][0];
 		Result[0][2] = m[2][0];
@@ -73,13 +73,13 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> rowMajor4(
-		const detail::tvec4<T>& v1, 
-		const detail::tvec4<T>& v2, 
-		const detail::tvec4<T>& v3, 
-		const detail::tvec4<T>& v4)
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> rowMajor4(
+		const detail::tvec4<T, P>& v1, 
+		const detail::tvec4<T, P>& v2, 
+		const detail::tvec4<T, P>& v3, 
+		const detail::tvec4<T, P>& v4)
 	{
-		detail::tmat4x4<T> Result;
+		detail::tmat4x4<T, P> Result;
 		Result[0][0] = v1.x;
 		Result[1][0] = v1.y;
 		Result[2][0] = v1.z;
@@ -100,10 +100,10 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> rowMajor4(
-		const detail::tmat4x4<T>& m)
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> rowMajor4(
+		const detail::tmat4x4<T, P>& m)
 	{
-		detail::tmat4x4<T> Result;
+		detail::tmat4x4<T, P> Result;
 		Result[0][0] = m[0][0];
 		Result[0][1] = m[1][0];
 		Result[0][2] = m[2][0];
@@ -124,50 +124,50 @@ namespace glm
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat2x2<T> colMajor2(
-		const detail::tvec2<T>& v1, 
-		const detail::tvec2<T>& v2)
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, P> colMajor2(
+		const detail::tvec2<T, P>& v1, 
+		const detail::tvec2<T, P>& v2)
 	{
-		return detail::tmat2x2<T>(v1, v2);
+		return detail::tmat2x2<T, P>(v1, v2);
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat2x2<T> colMajor2(
-		const detail::tmat2x2<T>& m)
+	GLM_FUNC_QUALIFIER detail::tmat2x2<T, P> colMajor2(
+		const detail::tmat2x2<T, P>& m)
 	{
-		return detail::tmat2x2<T>(m);
+		return detail::tmat2x2<T, P>(m);
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> colMajor3(
-		const detail::tvec3<T>& v1, 
-		const detail::tvec3<T>& v2, 
-		const detail::tvec3<T>& v3)
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> colMajor3(
+		const detail::tvec3<T, P>& v1, 
+		const detail::tvec3<T, P>& v2, 
+		const detail::tvec3<T, P>& v3)
 	{
-		return detail::tmat3x3<T>(v1, v2, v3);
+		return detail::tmat3x3<T, P>(v1, v2, v3);
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat3x3<T> colMajor3(
-		const detail::tmat3x3<T>& m)
+	GLM_FUNC_QUALIFIER detail::tmat3x3<T, P> colMajor3(
+		const detail::tmat3x3<T, P>& m)
 	{
-		return detail::tmat3x3<T>(m);
+		return detail::tmat3x3<T, P>(m);
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> colMajor4(
-		const detail::tvec4<T>& v1, 
-		const detail::tvec4<T>& v2, 
-		const detail::tvec4<T>& v3, 
-		const detail::tvec4<T>& v4)
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> colMajor4(
+		const detail::tvec4<T, P>& v1, 
+		const detail::tvec4<T, P>& v2, 
+		const detail::tvec4<T, P>& v3, 
+		const detail::tvec4<T, P>& v4)
 	{
-		return detail::tmat4x4<T>(v1, v2, v3, v4);
+		return detail::tmat4x4<T, P>(v1, v2, v3, v4);
 	}
 
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tmat4x4<T> colMajor4(
-		const detail::tmat4x4<T>& m)
+	GLM_FUNC_QUALIFIER detail::tmat4x4<T, P> colMajor4(
+		const detail::tmat4x4<T, P>& m)
 	{
-		return detail::tmat4x4<T>(m);
+		return detail::tmat4x4<T, P>(m);
 	}
 }//namespace glm

+ 21 - 21
glm/gtx/matrix_query.hpp

@@ -55,59 +55,59 @@ namespace glm
 
 	/// Return whether a matrix a null matrix.
 	/// From GLM_GTX_matrix_query extension.
-	template<typename T> 
+	template<typename T, precision P>
 	bool isNull(
-		detail::tmat2x2<T> const & m, 
+		detail::tmat2x2<T, P> const & m,
 		T const & epsilon/* = std::numeric_limits<T>::epsilon()*/);
 		
 	/// Return whether a matrix a null matrix.
 	/// From GLM_GTX_matrix_query extension.
-	template<typename T> 
+	template<typename T, precision P>
 	bool isNull(
-		detail::tmat3x3<T> const & m, 
+		detail::tmat3x3<T, P> const & m,
 		T const & epsilon/* = std::numeric_limits<T>::epsilon()*/);
 		
 	/// Return whether a matrix is a null matrix.
 	/// From GLM_GTX_matrix_query extension.
-	template<typename T> 
+	template<typename T, precision P>
 	bool isNull(
-		detail::tmat4x4<T> const & m, 
+		detail::tmat4x4<T, P> const & m,
 		T const & epsilon/* = std::numeric_limits<T>::epsilon()*/);
 			
-	/// Return whether a matrix is an identity matrix. 
+	/// Return whether a matrix is an identity matrix.
 	/// From GLM_GTX_matrix_query extension.
-	template<typename genType> 
+	template<typename genType>
 	bool isIdentity(
-		genType const & m, 
+		genType const & m,
 		typename genType::value_type const & epsilon/* = std::numeric_limits<typename genType::value_type>::epsilon()*/);
 
 	/// Return whether a matrix is a normalized matrix.
 	/// From GLM_GTX_matrix_query extension.
-	template<typename valType>   
+	template<typename T, precision P>
 	bool isNormalized(
-		detail::tmat2x2<valType> const & m, 
-		valType const & epsilon/* = std::numeric_limits<valType>::epsilon()*/);
+		detail::tmat2x2<T, P> const & m,
+		T const & epsilon/* = std::numeric_limits<T>::epsilon()*/);
 
 	/// Return whether a matrix is a normalized matrix.
 	/// From GLM_GTX_matrix_query extension.
-	template<typename valType>   
+	template<typename T, precision P>
 	bool isNormalized(
-		detail::tmat3x3<valType> const & m, 
-		valType const & epsilon/* = std::numeric_limits<valType>::epsilon()*/);
+		detail::tmat3x3<T, P> const & m,
+		T const & epsilon/* = std::numeric_limits<valType>::epsilon()*/);
 
 	/// Return whether a matrix is a normalized matrix.
 	/// From GLM_GTX_matrix_query extension.
-	template<typename valType>   
+	template<typename T, precision P>
 	bool isNormalized(
-		detail::tmat4x4<valType> const & m, 
-		valType const & epsilon/* = std::numeric_limits<valType>::epsilon()*/);
+		detail::tmat4x4<T, P> const & m,
+		T const & epsilon/* = std::numeric_limits<valType>::epsilon()*/);
 
 	/// Return whether a matrix is an orthonormalized matrix.
 	/// From GLM_GTX_matrix_query extension.
-	template<typename valType, template <typename> class matType> 
+	template<typename T, precision P, template <typename, precision> class matType>
 	bool isOrthogonal(
-		matType<valType> const & m, 
-		valType const & epsilon/* = std::numeric_limits<genType>::epsilon()*/);
+		matType<T, P> const & m,
+		T const & epsilon/* = std::numeric_limits<genType>::epsilon()*/);
 
 	/// @}
 }//namespace glm

+ 37 - 37
glm/gtx/matrix_query.inl

@@ -12,10 +12,10 @@
 
 namespace glm
 {
-	template<typename T> 
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER bool isNull
 	(
-		detail::tmat2x2<T> const & m, 
+		detail::tmat2x2<T, P> const & m,
 		T const & epsilon)
 	{
 		bool result = true;
@@ -24,10 +24,10 @@ namespace glm
 		return result;
 	}
 
-	template<typename T> 
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER bool isNull
 	(
-		detail::tmat3x3<T> const & m, 
+		detail::tmat3x3<T, P> const & m,
 		T const & epsilon
 	)
 	{
@@ -37,10 +37,10 @@ namespace glm
 		return result;
 	}
 
-	template<typename T> 
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER bool isNull
 	(
-		detail::tmat4x4<T> const & m, 
+		detail::tmat4x4<T, P> const & m,
 		T const & epsilon
 	)
 	{
@@ -50,10 +50,10 @@ namespace glm
 		return result;
 	}
 
-	template<typename genType> 
+	template<typename genType>
 	GLM_FUNC_QUALIFIER bool isIdentity
 	(
-		genType const & m, 
+		genType const & m,
 		typename genType::value_type const & epsilon
 	)
 	{
@@ -70,83 +70,83 @@ namespace glm
 		return result;
 	}
 
-	template<typename genType>  
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER bool isNormalized
 	(
-		detail::tmat2x2<genType> const & m, 
-		genType const & epsilon
+		detail::tmat2x2<T, P> const & m,
+		T const & epsilon
 	)
 	{
 		bool result(true);
-                for(typename detail::tmat2x2<genType>::size_type i(0); result && i < m.length(); ++i)
+		for(typename detail::tmat2x2<T, P>::size_type i(0); result && i < m.length(); ++i)
 			result = isNormalized(m[i], epsilon);
-                for(typename detail::tmat2x2<genType>::size_type i(0); result && i < m.length(); ++i)
+		for(typename detail::tmat2x2<T, P>::size_type i(0); result && i < m.length(); ++i)
 		{
-                        typename detail::tmat2x2<genType>::col_type v;
-                        for(typename detail::tmat2x2<genType>::size_type j(0); j < m.length(); ++j)
+			typename detail::tmat2x2<T, P>::col_type v;
+			for(typename detail::tmat2x2<T, P>::size_type j(0); j < m.length(); ++j)
 				v[j] = m[j][i];
 			result = isNormalized(v, epsilon);
 		}
 		return result;
 	}
 
-	template<typename genType>  
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER bool isNormalized
 	(
-		detail::tmat3x3<genType> const & m, 
-		genType const & epsilon
+		detail::tmat3x3<T, P> const & m,
+		T const & epsilon
 	)
 	{
 		bool result(true);
-                for(typename detail::tmat3x3<genType>::size_type i(0); result && i < m.length(); ++i)
+		for(typename detail::tmat3x3<T, P>::size_type i(0); result && i < m.length(); ++i)
 			result = isNormalized(m[i], epsilon);
-                for(typename detail::tmat3x3<genType>::size_type i(0); result && i < m.length(); ++i)
+		for(typename detail::tmat3x3<T, P>::size_type i(0); result && i < m.length(); ++i)
 		{
-                        typename detail::tmat3x3<genType>::col_type v;
-                        for(typename detail::tmat3x3<genType>::size_type j(0); j < m.length(); ++j)
+			typename detail::tmat3x3<T, P>::col_type v;
+			for(typename detail::tmat3x3<T, P>::size_type j(0); j < m.length(); ++j)
 				v[j] = m[j][i];
 			result = isNormalized(v, epsilon);
 		}
 		return result;
 	}
 
-	template<typename genType>  
+	template<typename T, precision P>
 	GLM_FUNC_QUALIFIER bool isNormalized
 	(
-		detail::tmat4x4<genType> const & m, 
-		genType const & epsilon
+		detail::tmat4x4<T, P> const & m,
+		T const & epsilon
 	)
 	{
 		bool result(true);
-                for(typename detail::tmat4x4<genType>::size_type i(0); result && i < m.length(); ++i)
+		for(typename detail::tmat4x4<T, P>::size_type i(0); result && i < m.length(); ++i)
 			result = isNormalized(m[i], epsilon);
-                for(typename detail::tmat4x4<genType>::size_type i(0); result && i < m.length(); ++i)
+		for(typename detail::tmat4x4<T, P>::size_type i(0); result && i < m.length(); ++i)
 		{
-                        typename detail::tmat4x4<genType>::col_type v;
-                        for(typename detail::tmat4x4<genType>::size_type j(0); j < m.length(); ++j)
+			typename detail::tmat4x4<T, P>::col_type v;
+			for(typename detail::tmat4x4<T, P>::size_type j(0); j < m.length(); ++j)
 				v[j] = m[j][i];
 			result = isNormalized(v, epsilon);
 		}
 		return result;
 	}
 
-	template<typename genType, template <typename> class matType>  
+	template<typename T, precision P, template <typename, precision> class matType>
 	GLM_FUNC_QUALIFIER bool isOrthogonal
 	(
-		matType<genType> const & m, 
-		genType const & epsilon
+		matType<T, P> const & m,
+		T const & epsilon
 	)
 	{
 		bool result(true);
-		for(typename matType<genType>::size_type i(0); result && i < m.length() - 1; ++i)
-		for(typename matType<genType>::size_type j(i + 1); result && j < m.length(); ++j)
+		for(typename matType<T, P>::size_type i(0); result && i < m.length() - 1; ++i)
+		for(typename matType<T, P>::size_type j(i + 1); result && j < m.length(); ++j)
 			result = areOrthogonal(m[i], m[j], epsilon);
 
 		if(result)
 		{
-			matType<genType> tmp = transpose(m);
-			for(typename matType<genType>::size_type i(0); result && i < m.length() - 1 ; ++i)
-			for(typename matType<genType>::size_type j(i + 1); result && j < m.length(); ++j)
+			matType<T, P> tmp = transpose(m);
+			for(typename matType<T, P>::size_type i(0); result && i < m.length() - 1 ; ++i)
+			for(typename matType<T, P>::size_type j(i + 1); result && j < m.length(); ++j)
 				result = areOrthogonal(tmp[i], tmp[j], epsilon);
 		}
 		return result;

+ 20 - 20
glm/gtx/norm.hpp

@@ -54,13 +54,13 @@ namespace glm
 
 	//! Returns the squared length of x.
 	//! From GLM_GTX_norm extension.
-	template <typename T> 
+	template <typename T>
 	T length2(
 		T const & x);
 
 	//! Returns the squared length of x.
 	//! From GLM_GTX_norm extension.
-	template <typename genType> 
+	template <typename genType>
 	typename genType::value_type length2(
 		genType const & x);
 		
@@ -68,55 +68,55 @@ namespace glm
 	//! From GLM_GTX_norm extension.
 	template <typename T>
 	T distance2(
-		T const & p0, 
+		T const & p0,
 		T const & p1);
 		
 	//! Returns the squared distance between p0 and p1, i.e., length(p0 - p1).
 	//! From GLM_GTX_norm extension.
-	template <typename genType> 
+	template <typename genType>
 	typename genType::value_type distance2(
-		genType const & p0, 
+		genType const & p0,
 		genType const & p1);
 
 	//! Returns the L1 norm between x and y.
 	//! From GLM_GTX_norm extension.
-	template <typename T>
+	template <typename T, precision P>
 	T l1Norm(
-		detail::tvec3<T> const & x,
-		detail::tvec3<T> const & y);
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y);
 		
 	//! Returns the L1 norm of v.
 	//! From GLM_GTX_norm extension.
-	template <typename T> 
+	template <typename T, precision P>
 	T l1Norm(
-		detail::tvec3<T> const & v);
+		detail::tvec3<T, P> const & v);
 		
 	//! Returns the L2 norm between x and y.
 	//! From GLM_GTX_norm extension.
-	template <typename T> 
+	template <typename T, precision P>
 	T l2Norm(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y);
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y);
 		
 	//! Returns the L2 norm of v.
 	//! From GLM_GTX_norm extension.
-	template <typename T> 
+	template <typename T, precision P>
 	T l2Norm(
-		detail::tvec3<T> const & x);
+		detail::tvec3<T, P> const & x);
 		
 	//! Returns the L norm between x and y.
 	//! From GLM_GTX_norm extension.
-	template <typename T> 
+	template <typename T, precision P>
 	T lxNorm(
-		detail::tvec3<T> const & x,
-		detail::tvec3<T> const & y,
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
 		unsigned int Depth);
 
 	//! Returns the L norm of v.
 	//! From GLM_GTX_norm extension.
-	template <typename T>
+	template <typename T, precision P>
 	T lxNorm(
-		detail::tvec3<T> const & x,
+		detail::tvec3<T, P> const & x,
 		unsigned int Depth);
 
 	/// @}

+ 32 - 32
glm/gtx/norm.inl

@@ -18,126 +18,126 @@ namespace glm
 		return x * x;
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T length2
 	(
-		detail::tvec2<T> const & x
+		detail::tvec2<T, P> const & x
 	)
 	{
 		return dot(x, x);
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T length2
 	(
-		detail::tvec3<T> const & x
+		detail::tvec3<T, P> const & x
 	)
 	{
 		return dot(x, x);
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T length2
 	(
-		detail::tvec4<T> const & x
+		detail::tvec4<T, P> const & x
 	)
 	{
 		return dot(x, x);
 	}
 
-	template <typename T> 
+	template <typename T>
 	GLM_FUNC_QUALIFIER T distance2
 	(
-		T const & p0, 
+		T const & p0,
 		T const & p1
 	)
 	{
 		return length2(p1 - p0);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T distance2
 	(
-		detail::tvec2<T> const & p0, 
-		detail::tvec2<T> const & p1
+		detail::tvec2<T, P> const & p0,
+		detail::tvec2<T, P> const & p1
 	)
 	{
 		return length2(p1 - p0);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T distance2
 	(
-		detail::tvec3<T> const & p0, 
-		detail::tvec3<T> const & p1
+		detail::tvec3<T, P> const & p0,
+		detail::tvec3<T, P> const & p1
 	)
 	{
 		return length2(p1 - p0);
 	}
 
-	template <typename T>
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T distance2
 	(
-		detail::tvec4<T> const & p0, 
-		detail::tvec4<T> const & p1
+		detail::tvec4<T, P> const & p0,
+		detail::tvec4<T, P> const & p1
 	)
 	{
 		return length2(p1 - p0);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T l1Norm
 	(
-		detail::tvec3<T> const & a, 
-		detail::tvec3<T> const & b
+		detail::tvec3<T, P> const & a,
+		detail::tvec3<T, P> const & b
 	)
 	{
 		return abs(b.x - a.x) + abs(b.y - a.y) + abs(b.z - a.z);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T l1Norm
 	(
-		detail::tvec3<T> const & v
+		detail::tvec3<T, P> const & v
 	)
 	{
 		return abs(v.x) + abs(v.y) + abs(v.z);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T l2Norm
 	(
-		detail::tvec3<T> const & a, 
-		detail::tvec3<T> const & b
+		detail::tvec3<T, P> const & a,
+		detail::tvec3<T, P> const & b
 	)
 	{
 		return length(b - a);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T l2Norm
 	(
-		detail::tvec3<T> const & v
+		detail::tvec3<T, P> const & v
 	)
 	{
 		return length(v);
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T lxNorm
 	(
-		detail::tvec3<T> const & x, 
-		detail::tvec3<T> const & y, 
+		detail::tvec3<T, P> const & x,
+		detail::tvec3<T, P> const & y,
 		unsigned int Depth
 	)
 	{
 		return pow(pow(y.x - x.x, T(Depth)) + pow(y.y - x.y, T(Depth)) + pow(y.z - x.z, T(Depth)), T(1) / T(Depth));
 	}
 
-	template <typename T> 
+	template <typename T, precision P>
 	GLM_FUNC_QUALIFIER T lxNorm
 	(
-		detail::tvec3<T> const & v, 
+		detail::tvec3<T, P> const & v,
 		unsigned int Depth
 	)
 	{

+ 4 - 4
glm/gtx/normal.hpp

@@ -54,10 +54,10 @@ namespace glm
 	//! Computes triangle normal from triangle points. 
 	//! From GLM_GTX_normal extension.
     template <typename T> 
-	detail::tvec3<T> triangleNormal(
-		detail::tvec3<T> const & p1, 
-		detail::tvec3<T> const & p2, 
-		detail::tvec3<T> const & p3);
+	detail::tvec3<T, P> triangleNormal(
+		detail::tvec3<T, P> const & p1, 
+		detail::tvec3<T, P> const & p2, 
+		detail::tvec3<T, P> const & p3);
 
 	/// @}
 }//namespace glm

+ 4 - 4
glm/gtx/normal.inl

@@ -10,11 +10,11 @@
 namespace glm
 {
 	template <typename T> 
-	GLM_FUNC_QUALIFIER detail::tvec3<T> triangleNormal
+	GLM_FUNC_QUALIFIER detail::tvec3<T, P> triangleNormal
 	(
-		detail::tvec3<T> const & p1, 
-		detail::tvec3<T> const & p2, 
-		detail::tvec3<T> const & p3
+		detail::tvec3<T, P> const & p1, 
+		detail::tvec3<T, P> const & p2, 
+		detail::tvec3<T, P> const & p3
 	)
 	{
 		return normalize(cross(p1 - p2, p1 - p3));

+ 14 - 11
glm/gtx/optimum_pow.hpp

@@ -53,34 +53,37 @@ namespace gtx
 
 	//! Returns x raised to the power of 2.
 	//! From GLM_GTX_optimum_pow extension.
-    template <typename genType> 
+	template <typename genType>
 	genType pow2(const genType& x);
 
 	//! Returns x raised to the power of 3.
 	//! From GLM_GTX_optimum_pow extension.
-    template <typename genType> 
+	template <typename genType>
 	genType pow3(const genType& x);
 
 	//! Returns x raised to the power of 4.
 	//! From GLM_GTX_optimum_pow extension.
-	template <typename genType> 
+	template <typename genType>
 	genType pow4(const genType& x);
-        
-	//! Checks if the parameter is a power of 2 number. 
+
+	//! Checks if the parameter is a power of 2 number.
 	//! From GLM_GTX_optimum_pow extension.
-    bool powOfTwo(int num);
+	bool powOfTwo(int num);
 
 	//! Checks to determine if the parameter component are power of 2 numbers.
 	//! From GLM_GTX_optimum_pow extension.
-    detail::tvec2<bool> powOfTwo(const detail::tvec2<int>& x);
+	template <precision P>
+	detail::tvec2<bool, P> powOfTwo(detail::tvec2<int, P> const & x);
 
-	//! Checks to determine if the parameter component are power of 2 numbers. 
+	//! Checks to determine if the parameter component are power of 2 numbers.
 	//! From GLM_GTX_optimum_pow extension.
-    detail::tvec3<bool> powOfTwo(const detail::tvec3<int>& x);
+	template <precision P>
+	detail::tvec3<bool, P> powOfTwo(detail::tvec3<int, P> const & x);
 
-	//! Checks to determine if the parameter component are power of 2 numbers. 
+	//! Checks to determine if the parameter component are power of 2 numbers.
 	//! From GLM_GTX_optimum_pow extension.
-    detail::tvec4<bool> powOfTwo(const detail::tvec4<int>& x);
+	template <precision P>
+	detail::tvec4<bool, P> powOfTwo(detail::tvec4<int, P> const & x);
 
 	/// @}
 }//namespace gtx

+ 16 - 13
glm/gtx/optimum_pow.inl

@@ -9,22 +9,22 @@
 
 namespace glm
 {
-	template <typename genType> 
-	GLM_FUNC_QUALIFIER genType pow2(const genType& x)
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType pow2(genType const & x)
 	{
 		return x * x;
 	}
 
-	template <typename genType> 
-	GLM_FUNC_QUALIFIER genType pow3(const genType& x)
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType pow3(genType const & x)
 	{
 		return x * x * x;
 	}
 
-	template <typename genType> 
-	GLM_FUNC_QUALIFIER genType pow4(const genType& x)
+	template <typename genType>
+	GLM_FUNC_QUALIFIER genType pow4(genType const & x)
 	{
-		return x * x * x * x;
+		return (x * x) * (x * x);
 	}
 
 	GLM_FUNC_QUALIFIER bool powOfTwo(int x)
@@ -32,24 +32,27 @@ namespace glm
 		return !(x & (x - 1));
 	}
 
-	GLM_FUNC_QUALIFIER detail::tvec2<bool> powOfTwo(const detail::tvec2<int>& x)
+	template <precision P>
+	GLM_FUNC_QUALIFIER detail::tvec2<bool, P> powOfTwo(detail::tvec2<int, P> const & x)
 	{
-		return detail::tvec2<bool>(
+		return detail::tvec2<bool, P>(
 			powOfTwo(x.x),
 			powOfTwo(x.y));
 	}
 
-	GLM_FUNC_QUALIFIER detail::tvec3<bool> powOfTwo(const detail::tvec3<int>& x)
+	template <precision P>
+	GLM_FUNC_QUALIFIER detail::tvec3<bool, P> powOfTwo(detail::tvec3<int, P> const & x)
 	{
-		return detail::tvec3<bool>(
+		return detail::tvec3<bool, P>(
 			powOfTwo(x.x),
 			powOfTwo(x.y),
 			powOfTwo(x.z));
 	}
 
-	GLM_FUNC_QUALIFIER detail::tvec4<bool> powOfTwo(const detail::tvec4<int>& x)
+	template <precision P>
+	GLM_FUNC_QUALIFIER detail::tvec4<bool, P> powOfTwo(detail::tvec4<int, P> const & x)
 	{
-		return detail::tvec4<bool>(
+		return detail::tvec4<bool, P>(
 			powOfTwo(x.x),
 			powOfTwo(x.y),
 			powOfTwo(x.z),

+ 5 - 5
glm/gtx/orthonormalize.hpp

@@ -54,15 +54,15 @@ namespace glm
 	//! Returns the orthonormalized matrix of m.
 	//! From GLM_GTX_orthonormalize extension.
 	template <typename T> 
-	detail::tmat3x3<T> orthonormalize(
-		const detail::tmat3x3<T>& m);
+	detail::tmat3x3<T, P> orthonormalize(
+		const detail::tmat3x3<T, P>& m);
 		
     //! Orthonormalizes x according y.
 	//! From GLM_GTX_orthonormalize extension.
 	template <typename T> 
-	detail::tvec3<T> orthonormalize(
-		const detail::tvec3<T>& x, 
-		const detail::tvec3<T>& y);
+	detail::tvec3<T, P> orthonormalize(
+		const detail::tvec3<T, P>& x, 
+		const detail::tvec3<T, P>& y);
 
 	/// @}
 }//namespace glm

部分文件因为文件数量过多而无法显示