Browse Source

Added initializer lists

Christophe Riccio 12 years ago
parent
commit
71855943e0

+ 7 - 0
glm/core/setup.hpp

@@ -511,6 +511,13 @@
 	((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC46)) || \
 	__has_feature(cxx_constexpr))
 
+// N2672
+#define GLM_HAS_INITIALIZER_LISTS ( \
+	(GLM_LANG & GLM_LANG_CXX11_FLAG) || \
+	((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_VC) && (GLM_COMPILER >= GLM_COMPILER_VC2012)) || \
+	((GLM_LANG & GLM_LANG_CXX0X_FLAG) && (GLM_COMPILER & GLM_COMPILER_GCC) && (GLM_COMPILER >= GLM_COMPILER_GCC44)) || \
+	__has_feature(cxx_generalized_initializers))
+
 // OpenMP
 #ifdef _OPENMP 
 #	if(GLM_COMPILER & GLM_COMPILER_GCC)

+ 9 - 0
glm/core/type_vec1.hpp

@@ -38,6 +38,10 @@
 #		include "_swizzle_func.hpp"
 #	endif
 #endif //GLM_SWIZZLE
+#if(GLM_HAS_INITIALIZER_LISTS)
+#	include <initializer_list>
+#endif //GLM_HAS_INITIALIZER_LISTS
+#include <cstddef>
 
 namespace glm{
 namespace detail
@@ -78,6 +82,11 @@ namespace detail
 		template <precision Q>
 		GLM_FUNC_DECL tvec1(tvec1<T, Q> const & v);
 
+#if(GLM_HAS_INITIALIZER_LISTS)
+		template <typename U>
+		GLM_FUNC_DECL tvec1(std::initializer_list<U> const & v);
+#endif//GLM_HAS_INITIALIZER_LISTS
+
 		//////////////////////////////////////
 		// Explicit basic constructors
 

+ 10 - 0
glm/core/type_vec1.inl

@@ -71,6 +71,16 @@ namespace detail
 		x(v.x)
 	{}
 
+#if(GLM_HAS_INITIALIZER_LISTS)
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec1<T, P>::tvec1(std::initializer_list<U> const & v) :
+		x(static_cast<T>(v.begin()[0]))
+	{
+		assert(v.size() >= this->length());
+	}
+#endif//GLM_HAS_INITIALIZER_LISTS
+
 	//////////////////////////////////////
 	// Explicit basic constructors
 

+ 8 - 0
glm/core/type_vec2.hpp

@@ -38,6 +38,9 @@
 #		include "_swizzle_func.hpp"
 #	endif
 #endif //GLM_SWIZZLE
+#if(GLM_HAS_INITIALIZER_LISTS)
+#	include <initializer_list>
+#endif //GLM_HAS_INITIALIZER_LISTS
 #include <cstddef>
 
 namespace glm{
@@ -103,6 +106,11 @@ namespace detail
 		template <precision Q>
 		GLM_FUNC_DECL tvec2(tvec2<T, Q> const & v);
 
+#if(GLM_HAS_INITIALIZER_LISTS)
+		template <typename U>
+		GLM_FUNC_DECL tvec2(std::initializer_list<U> const & v);
+#endif//GLM_HAS_INITIALIZER_LISTS
+
 		//////////////////////////////////////
 		// Explicit basic constructors
 

+ 11 - 0
glm/core/type_vec2.inl

@@ -74,6 +74,17 @@ namespace detail
 		y(v.y)
 	{}
 
+#if(GLM_HAS_INITIALIZER_LISTS)
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec2<T, P>::tvec2(std::initializer_list<U> const & v) :
+		x(static_cast<T>(v.begin()[0])),
+		y(static_cast<T>(v.begin()[1]))
+	{
+		assert(v.size() >= this->length());
+	}
+#endif//GLM_HAS_INITIALIZER_LISTS
+
 	//////////////////////////////////////
 	// Explicit basic constructors
 

+ 8 - 0
glm/core/type_vec3.hpp

@@ -38,6 +38,9 @@
 #		include "_swizzle_func.hpp"
 #	endif
 #endif //GLM_SWIZZLE
+#if(GLM_HAS_INITIALIZER_LISTS)
+#	include <initializer_list>
+#endif //GLM_HAS_INITIALIZER_LISTS
 #include <cstddef>
 
 namespace glm{
@@ -104,6 +107,11 @@ namespace detail
 		template <precision Q>
 		GLM_FUNC_DECL tvec3(tvec3<T, Q> const & v);
 
+#if(GLM_HAS_INITIALIZER_LISTS)
+		template <typename U>
+		GLM_FUNC_DECL tvec3(std::initializer_list<U> const & v);
+#endif//GLM_HAS_INITIALIZER_LISTS
+
 		//////////////////////////////////////
 		// Explicit basic constructors
 

+ 12 - 0
glm/core/type_vec3.inl

@@ -77,6 +77,18 @@ namespace detail
 		z(v.z)
 	{}
 
+#if(GLM_HAS_INITIALIZER_LISTS)
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec3<T, P>::tvec3(std::initializer_list<U> const & v) :
+		x(static_cast<T>(v.begin()[0])),
+		y(static_cast<T>(v.begin()[1])),
+		z(static_cast<T>(v.begin()[2]))
+	{
+		assert(v.size() >= this->length());
+	}
+#endif//GLM_HAS_INITIALIZER_LISTS
+
 	//////////////////////////////////////
 	// Explicit basic constructors
 

+ 8 - 0
glm/core/type_vec4.hpp

@@ -39,6 +39,9 @@
 #		include "_swizzle_func.hpp"
 #	endif
 #endif //GLM_SWIZZLE
+#if(GLM_HAS_INITIALIZER_LISTS)
+#	include <initializer_list>
+#endif //GLM_HAS_INITIALIZER_LISTS
 #include <cstddef>
 
 namespace glm{
@@ -106,6 +109,11 @@ namespace detail
 		template <precision Q>
 		GLM_FUNC_DECL tvec4(tvec4<T, Q> const & v);
 
+#if(GLM_HAS_INITIALIZER_LISTS)
+		template <typename U>
+		GLM_FUNC_DECL tvec4(std::initializer_list<U> const & v);
+#endif//GLM_HAS_INITIALIZER_LISTS
+
 		//////////////////////////////////////
 		// Explicit basic constructors
 

+ 13 - 0
glm/core/type_vec4.inl

@@ -80,6 +80,19 @@ namespace detail
 		w(v.w)
 	{}
 
+#if(GLM_HAS_INITIALIZER_LISTS)
+	template <typename T, precision P>
+	template <typename U>
+	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4(std::initializer_list<U> const & v) :
+		x(static_cast<T>(v.begin()[0])),
+		y(static_cast<T>(v.begin()[1])),
+		z(static_cast<T>(v.begin()[2])),
+		w(static_cast<T>(v.begin()[3]))
+	{
+		assert(v.size() >= this->length());
+	}
+#endif//GLM_HAS_INITIALIZER_LISTS
+
 	//////////////////////////////////////
 	// Explicit basic constructors
 

+ 1 - 0
readme.txt

@@ -66,6 +66,7 @@ GLM 0.9.5.0: 2013-XX-XX
 - Allowed including individual core feature
 - Increased unit tests completness
 - Added creating of a quaternion  from two vectors
+- Added C++11 initializer lists
 
 ================================================================================
 GLM 0.9.4.6: 2013-09-20

+ 77 - 0
test/core/core_type_vec4.cpp

@@ -11,6 +11,7 @@
 #include <glm/core/type_vec3.hpp>
 #include <glm/core/type_vec4.hpp>
 #include <glm/core/func_vector_relational.hpp>
+#include <ctime>
 #include <vector>
 
 template <int Value>
@@ -39,6 +40,10 @@ int test_vec4_ctor()
 {
 	int Error = 0;
 	
+#if(GLM_HAS_INITIALIZER_LISTS)
+	glm::vec4 v{0, 1, 2, 3};
+#endif
+
 	{
 		glm::vec4 A(1);
 		glm::vec4 B(1, 1, 1, 1);
@@ -282,6 +287,74 @@ int test_operator_increment()
 	return Error;
 }
 
+struct AoS
+{
+	glm::vec4 A;
+	glm::vec3 B;
+	glm::vec3 C;
+	glm::vec2 D;
+};
+
+int test_vec4_perf_AoS(std::size_t Size)
+{
+	int Error(0);
+
+	std::vector<AoS> In;
+	std::vector<AoS> Out;
+	In.resize(Size);
+	Out.resize(Size);
+
+	std::clock_t StartTime = std::clock();
+
+	for(std::size_t i = 0; i < In.size(); ++i)
+		Out[i] = In[i];
+
+	std::clock_t EndTime = std::clock();
+
+	printf("AoS: %d\n", EndTime - StartTime);
+
+	return Error;
+}
+
+int test_vec4_perf_SoA(std::size_t Size)
+{
+	int Error(0);
+
+	std::vector<glm::vec4> InA;
+	std::vector<glm::vec3> InB;
+	std::vector<glm::vec3> InC;
+	std::vector<glm::vec2> InD;
+	std::vector<glm::vec4> OutA;
+	std::vector<glm::vec3> OutB;
+	std::vector<glm::vec3> OutC;
+	std::vector<glm::vec2> OutD;
+
+	InA.resize(Size);
+	InB.resize(Size);
+	InC.resize(Size);
+	InD.resize(Size);
+	OutA.resize(Size);
+	OutB.resize(Size);
+	OutC.resize(Size);
+	OutD.resize(Size);
+
+	std::clock_t StartTime = std::clock();
+
+	for(std::size_t i = 0; i < InA.size(); ++i)
+	{
+		OutA[i] = InA[i];
+		OutB[i] = InB[i];
+		OutC[i] = InC[i];
+		OutD[i] = InD[i];
+	}
+
+	std::clock_t EndTime = std::clock();
+
+	printf("SoA: %d\n", EndTime - StartTime);
+
+	return Error;
+}
+
 int main()
 {
 	//__m128 DataA = swizzle<X, Y, Z, W>(glm::vec4(1.0f, 2.0f, 3.0f, 4.0f));
@@ -289,6 +362,10 @@ int main()
 
 	int Error(0);
 	
+	std::size_t const Size(100000000);
+
+	Error += test_vec4_perf_AoS(Size);
+	Error += test_vec4_perf_SoA(Size);
 	Error += test_vec4_ctor();
 	Error += test_vec4_size();
 	Error += test_vec4_operators();

+ 33 - 0
test/gtc/gtc_quaternion.cpp

@@ -197,6 +197,37 @@ int test_quat_slerp()
 	return Error;
 }
 
+int test_quat_mul()
+{
+	int Error(0);
+
+	glm::quat temp1 = glm::normalize(glm::quat(1.0f, glm::vec3(0.0, 1.0, 0.0)));
+	glm::quat temp2 = glm::normalize(glm::quat(0.5f, glm::vec3(1.0, 0.0, 0.0)));
+
+	glm::vec3 transformed0 = (temp1 * glm::vec3(0.0, 1.0, 0.0) * glm::inverse(temp1));
+	glm::vec3 temp4 = temp2 * transformed0 * glm::inverse(temp2);
+
+	glm::quat temp5 = glm::normalize(temp1 * temp2);
+	glm::vec3 temp6 = temp5 * glm::vec3(0.0, 1.0, 0.0) * glm::inverse(temp5);
+
+	return Error;
+}
+
+int test_quat_two_axis_ctr()
+{
+	int Error(0);
+
+	glm::quat q1(glm::vec3(1, 0, 0), glm::vec3(0, 1, 0));
+	glm::vec3 v1 = q1 * glm::vec3(1, 0, 0);
+	Error += glm::all(glm::epsilonEqual(v1, glm::vec3(0, 1, 0), 0.0001f)) ? 0 : 1;
+
+	glm::quat q2 = q1 * q1;
+	glm::vec3 v2 = q2 * glm::vec3(1, 0, 0);
+	Error += glm::all(glm::epsilonEqual(v2, glm::vec3(-1, 0, 0), 0.0001f)) ? 0 : 1;
+
+	return Error;
+}
+
 int test_quat_type()
 {
 	glm::quat A;
@@ -209,6 +240,8 @@ int main()
 {
 	int Error(0);
 
+	Error += test_quat_two_axis_ctr();
+	Error += test_quat_mul();
 	Error += test_quat_precision();
 	Error += test_quat_type();
 	Error += test_quat_angle();