浏览代码

Fixed merge

Christophe Riccio 14 年之前
父节点
当前提交
b5c8d9e812
共有 8 个文件被更改,包括 872 次插入503 次删除
  1. 1 0
      CMakeLists.txt
  2. 734 464
      glm/core/_swizzle.hpp
  3. 1 0
      glm/core/func_geometric.inl
  4. 6 0
      glm/core/type_vec2.hpp
  5. 8 2
      glm/core/type_vec3.hpp
  6. 6 0
      glm/core/type_vec4.hpp
  7. 106 37
      test/core/core_type_vec3.cpp
  8. 10 0
      test/glm.cppcheck

+ 1 - 0
CMakeLists.txt

@@ -12,6 +12,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
 	#add_definitions(-S)
 	#add_definitions(-s)
 	add_definitions(-msse2)
+	add_definitions(-std=c++0x )
 	#add_definitions(-m32)
 	#add_definitions(-mfpmath=387)
 	#add_definitions(-ffast-math)

+ 734 - 464
glm/core/_swizzle.hpp

@@ -48,520 +48,790 @@ namespace glm
 	};
 }//namespace glm
 
-
 namespace glm{
 namespace detail
 {
     //! Internal class for implementing swizzle operators
-    /*!
-        Template parameters:
-
-        Type    = type of scalar values (e.g. float, double)
-        Class   = class the swizzle is applies to (e.g. vector3f)
-        N       = number of components in the vector (e.g. 3)
-        E0...3  = what index the n-th element of this swizzle refers to
-    */
-    template <typename Type, typename Class, int N, int E0, int E1, int E2, int E3, int DUPLICATE_ELEMENTS>
-    struct swizzle_base
+    template <typename T, int N>
+    struct _swizzle_base0
     {
-        swizzle_base& operator= (const Class& that)
-        {
-            static const int offset_dst[4] = { E0, E1, E2, E3 };
-
-            Type t[N];
-            for (int i = 0; i < N; ++i)
-                t[i] = that[i];
-            for (int i = 0; i < N; ++i)
-                elem(offset_dst[i]) = t[i];
-
-            return *this;
-        }
-
-        swizzle_base& operator= (const Type& t)
-        {
-            static const int offset_dst[4] = { E0, E1, E2, E3 };
-
-            for (int i = 0; i < N; ++i)
-                elem(offset_dst[i]) = t;
-
-            return *this;
-        }
+        typedef T       value_type;
 
     protected:
-        Type&   elem   (size_t i) { return (reinterpret_cast<Type*>(_buffer))[i]; }
+        value_type&         elem   (size_t i)       { return (reinterpret_cast<value_type*>(_buffer))[i]; }
+        const value_type&   elem   (size_t i) const { return (reinterpret_cast<const value_type*>(_buffer))[i]; }
 
         // Use an opaque buffer to *ensure* the compiler doesn't call a constructor.
-        // Otherwise, a vec4 containg all swizzles might end up with 1000s of 
-        // constructor calls
-        char    _buffer[sizeof(Type) * N];
+        // The size 1 buffer is assumed to aligned to the actual members so that the
+        // elem() 
+        char    _buffer[1];
     };
 
-    template <typename Type, typename Class, int N, int E0, int E1, int E2, int E3>
-    struct swizzle_base<Type,Class,N,E0,E1,E2,E3,1>
+    template <typename T, typename V, int E0, int E1, int E2, int E3, int N>
+    struct _swizzle_base1 : public _swizzle_base0<T,N>
     {
-        struct Stub {};
-        swizzle_base& operator= (const Stub& that) {}
-          
-    protected:
-        Type&   elem   (size_t i) { return (reinterpret_cast<Type*>(_buffer))[i]; }
-        char    _buffer[sizeof(Type) * N];      
     };
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1>
-    struct swizzle2 : public swizzle_base<T,P,2,E0,E1,0,0,(E0 == E1)>
+    template <typename T, typename V, int E0, int E1>
+    struct _swizzle_base1<T,V,E0,E1,-1,-2,2> : public _swizzle_base0<T,2>
     {
-        using swizzle_base<T,P,2,E0,E1,0,0,(E0 == E1)>::operator=;
-        operator P () { return P(this->elem(E0), this->elem(E1)); }
+        V operator ()()  const { return V(this->elem(E0), this->elem(E1)); }
     };
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1, int E2>
-    struct swizzle2_3 : public swizzle_base<T,P,2,E0,E1,E2,0,1>
+    template <typename T, typename V, int E0, int E1, int E2>
+    struct _swizzle_base1<T,V,E0,E1,E2,-1,3> : public _swizzle_base0<T,3>
     {
-        using swizzle_base<T,P,2,E0,E1,E2,0,1>::operator=;
-        operator P () { return P(this->elem(E0), this->elem(E1), this->elem(E2)); }
+        V operator ()()  const { return V(this->elem(E0), this->elem(E1), this->elem(E2)); }
     };
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1, int E2, int E3>
-    struct swizzle2_4 : public swizzle_base<T,P,2,E0,E1,E2,E3,1>
-    {
-        using swizzle_base<T,P,2,E0,E1,E2,E3,1>::operator=;
-        operator P () { return P(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
+    template <typename T, typename V, int E0, int E1, int E2, int E3>
+    struct _swizzle_base1<T,V,E0,E1,E2,E3,4> : public _swizzle_base0<T,4>
+    { 
+        V operator ()()  const { return V(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
     };
 
     //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1, int E2>
-    struct swizzle3 : public swizzle_base<T,P,3,E0,E1,E2,0,(E0==E1||E0==E2||E1==E2)>
-    {
-        using swizzle_base<T,P,3,E0,E1,E2,0,(E0==E1||E0==E2||E1==E2)>::operator=;
-        operator P () { return P(this->elem(E0), this->elem(E1), this->elem(E2)); }
-    };
+    /*!
+        Template parameters:
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1>
-    struct swizzle3_2 : public swizzle_base<T,P,2,E0,E1,0,0,(E0==E1)>
+        ValueType = type of scalar values (e.g. float, double)
+        VecType   = class the swizzle is applies to (e.g. tvec3<float>)
+        N         = number of components in the vector (e.g. 3)
+        E0...3    = what index the n-th element of this swizzle refers to in the unswizzled vec
+        
+        DUPLICATE_ELEMENTS = 1 if there is a repeated element, 0 otherwise (used to specialize swizzles
+            containing duplicate elements so that they cannot be used as r-values).            
+    */
+    template <typename ValueType, typename VecType, int N, int E0, int E1, int E2, int E3, int DUPLICATE_ELEMENTS>
+    struct _swizzle_base2 : public _swizzle_base1<ValueType,VecType,E0,E1,E2,E3,N>
     {
-        using swizzle_base<T,P,2,E0,E1,0,0,(E0==E1)>::operator=;
-        operator P () { return P(this->elem(E0), this->elem(E1)); }
+		typedef VecType vec_type;
+		typedef ValueType value_type;
+
+		_swizzle_base2& operator= (const ValueType& t)
+		{
+			for (int i = 0; i < N; ++i)
+				(*this)[i] = t;
+			return *this;
+		}
+
+		_swizzle_base2& operator= (const VecType& that)
+		{
+			struct op { 
+				void operator() (value_type& e, value_type& t) { e = t; } 
+			};
+			_apply_op(that, op());
+			return *this;
+		}
+
+		void operator -= (const VecType& that)
+		{
+			struct op { 
+				void operator() (value_type& e, value_type& t) { e -= t; } 
+			};
+			_apply_op(that, op());
+		}
+
+		void operator += (const VecType& that)
+		{
+			struct op { 
+				void operator() (value_type& e, value_type& t) { e += t; } 
+			};
+			_apply_op(that, op());
+		}
+
+		void operator *= (const VecType& that)
+		{
+			struct op { 
+				void operator() (value_type& e, value_type& t) { e *= t; } 
+			};
+			_apply_op(that, op());
+		}
+
+		void operator /= (const VecType& that)
+		{
+			struct op { 
+				void operator() (value_type& e, value_type& t) { e /= t; } 
+			};
+			_apply_op(that, op());
+		}
+
+		value_type& operator[]  (size_t i)
+		{
+			static const int offset_dst[4] = { E0, E1, E2, E3 };
+			return this->elem(offset_dst[i]);
+		}
+		value_type  operator[]  (size_t i) const
+		{
+			static const int offset_dst[4] = { E0, E1, E2, E3 };
+			return this->elem(offset_dst[i]);
+		}
+	protected:
+		template <typename T>
+		void _apply_op(const VecType& that, T op)
+		{
+			// Make a copy of the data in this == &that.
+			// The copier should optimize out the copy in cases where the function is
+			// properly inlined and the copy is not necessary.
+			ValueType t[N];
+			for (int i = 0; i < N; ++i)
+				t[i] = that[i];
+			for (int i = 0; i < N; ++i)
+				op( (*this)[i], t[i] );
+		}
     };
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1, int E2, int E3>
-    struct swizzle3_4 : public swizzle_base<T,P,3,E0,E1,E2,E3,1>
-    {
-        using swizzle_base<T,P,3,E0,E1,E2,E3,1>::operator=;
-        operator P () { return P(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
-    };
+	//! Specialization for swizzles containing duplicate elements.  These cannot be modified.
+	template <typename ValueType, typename VecType, int N, int E0, int E1, int E2, int E3>
+	struct _swizzle_base2<ValueType,VecType,N,E0,E1,E2,E3,1> : public _swizzle_base1<ValueType,VecType,E0,E1,E2,E3,N>
+	{
+		typedef VecType         vec_type;        
+		typedef ValueType       value_type;
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1, int E2, int E3>
-    struct swizzle4 : public swizzle_base<T,P,4,E0,E1,E2,E3,(E0==E1||E0==E2||E0==E3||E1==E2||E1==E3||E2==E3)>
-    {
-        using swizzle_base<T,P,4,E0,E1,E2,E3,(E0==E1||E0==E2||E0==E3||E1==E2||E1==E3||E2==E3)>::operator=;
-        operator P () { return P(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
-    };
+		struct Stub {};
+		_swizzle_base2& operator= (const Stub& that) {}
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1>
-    struct swizzle4_2 : public swizzle_base<T,P,2,E0,E1,0,0,(E0==E1)>
-    {
-        using swizzle_base<T,P,2,E0,E1,0,0,(E0==E1)>::operator=;
-        operator P () { return P(this->elem(E0), this->elem(E1)); }
-    };
+		value_type  operator[]  (size_t i) const
+		{
+			static const int offset_dst[4] = { E0, E1, E2, E3 };
+			return this->elem(offset_dst[i]);
+		} 
+	};
 
+	template <int N,typename ValueType, typename VecType, int E0,int E1,int E2,int E3>
+	struct swizzle : public _swizzle_base2<ValueType,VecType,N,E0,E1,E2,E3,(E0==E1||E0==E2||E0==E3||E1==E2||E1==E3||E2==E3)>
+	{
+		typedef _swizzle_base2<ValueType,VecType,N,E0,E1,E2,E3,(E0==E1||E0==E2||E0==E3||E1==E2||E1==E3||E2==E3)> base_type;
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1, int E2>
-    struct swizzle4_3 : public swizzle_base<T,P,4,E0,E1,E2,0,(E0==E1||E0==E2||E1==E2)>
-    {
-        using swizzle_base<T,P,4,E0,E1,E2,0,(E0==E1||E0==E2||E1==E2)>::operator=;
-        operator P () { return P(this->elem(E0), this->elem(E1), this->elem(E2)); }
-    };
+		using base_type::operator=;
+
+		operator VecType () const { return (*this)(); }
+	};
 
+//
+// To prevent the C++ syntax from getting entirely overwhelming, define some alias macros
+//
+#define _GLM_SWIZZLE_TEMPLATE1   template <int N, typename T, typename V, int E0, int E1, int E2, int E3>
+#define _GLM_SWIZZLE_TEMPLATE2   template <int N, typename T, typename V, int E0, int E1, int E2, int E3, int F0, int F1, int F2, int F3>
+#define _GLM_SWIZZLE_TYPE1       glm::detail::swizzle<N,T,V,E0,E1,E2,E3>
+#define _GLM_SWIZZLE_TYPE2       glm::detail::swizzle<N,T,V,F0,F1,F2,F3>
+
+//
+// Wrapper for a binary operator (e.g. u.yy + v.zy)
+//
+#define _GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND)                 \
+	_GLM_SWIZZLE_TEMPLATE2                                                          \
+	V operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b)  \
+	{                                                                               \
+		return a() OPERAND b();                                                     \
+	}                                                                               \
+	_GLM_SWIZZLE_TEMPLATE1                                                          \
+	V operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const V& b)                   \
+	{                                                                               \
+		return a() OPERAND b;                                                       \
+	}                                                                               \
+	_GLM_SWIZZLE_TEMPLATE1                                                          \
+	V operator OPERAND ( const V& a, const _GLM_SWIZZLE_TYPE1& b)                   \
+	{                                                                               \
+		return a OPERAND b();                                                       \
+	}
+
+//
+// Wrapper for a operand between a swizzle and a binary (e.g. 1.0f - u.xyz)
+//
+#define _GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(OPERAND)                 \
+	_GLM_SWIZZLE_TEMPLATE1                                                          \
+	V operator OPERAND ( const _GLM_SWIZZLE_TYPE1& a, const T& b)                   \
+	{                                                                               \
+		return a() OPERAND b;                                                       \
+	}                                                                               \
+	_GLM_SWIZZLE_TEMPLATE1                                                          \
+	V operator OPERAND ( const T& a, const _GLM_SWIZZLE_TYPE1& b)                   \
+	{                                                                               \
+		return a OPERAND b();                                                       \
+	}
+
+//
+// Macro for wrapping a function taking one argument (e.g. abs())
+//
+#define _GLM_SWIZZLE_FUNCTION_1_ARGS(RETURN_TYPE,FUNCTION)                          \
+	_GLM_SWIZZLE_TEMPLATE1                                                          \
+	typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a)  \
+	{                                                                               \
+		return FUNCTION(a());                                                       \
+	}
+
+//
+// Macro for wrapping a function taking two vector arguments (e.g. dot()).
+//
+#define _GLM_SWIZZLE_FUNCTION_2_ARGS(RETURN_TYPE,FUNCTION)                                                      \
+	_GLM_SWIZZLE_TEMPLATE2                                                                                      \
+	typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b) \
+	{                                                                                                           \
+		return FUNCTION(a(), b());                                                                              \
+	}                                                                                                           \
+	_GLM_SWIZZLE_TEMPLATE1                                                                                      \
+	typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE1& b) \
+	{                                                                                                           \
+		return FUNCTION(a(), b());                                                                              \
+	}                                                                                                           \
+	_GLM_SWIZZLE_TEMPLATE1                                                                                      \
+	typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const typename V& b)         \
+	{                                                                                                           \
+		return FUNCTION(a(), b);                                                                                \
+	}                                                                                                           \
+	_GLM_SWIZZLE_TEMPLATE1                                                                                      \
+	typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const V& a, const _GLM_SWIZZLE_TYPE1& b)                  \
+	{                                                                                                           \
+		return FUNCTION(a, b());                                                                                \
+	} 
+
+//
+// Macro for wrapping a function take 2 vec arguments followed by a scalar (e.g. mix()).
+//
+#define _GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(RETURN_TYPE,FUNCTION)                                                             \
+	_GLM_SWIZZLE_TEMPLATE2                                                                                                    \
+	typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE2& b, const T& c)   \
+	{                                                                                                                         \
+		return FUNCTION(a(), b(), c);                                                                                         \
+	}                                                                                                                         \
+	_GLM_SWIZZLE_TEMPLATE1                                                                                                    \
+	typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const _GLM_SWIZZLE_TYPE1& b, const T& c)   \
+	{                                                                                                                         \
+		return FUNCTION(a(), b(), c);                                                                                         \
+	}                                                                                                                         \
+	_GLM_SWIZZLE_TEMPLATE1                                                                                                    \
+	typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const _GLM_SWIZZLE_TYPE1& a, const typename S0::vec_type& b, const T& c)\
+	{                                                                                                                         \
+		return FUNCTION(a(), b, c);                                                                                           \
+	}                                                                                                                         \
+	_GLM_SWIZZLE_TEMPLATE1                                                                                                    \
+	typename _GLM_SWIZZLE_TYPE1::RETURN_TYPE FUNCTION(const typename V& a, const _GLM_SWIZZLE_TYPE1& b, const T& c)           \
+	{                                                                                                                         \
+		return FUNCTION(a, b(), c);                                                                                           \
+	} 
+ 
 }//namespace detail 
 }//namespace glm
 
+namespace glm
+{
+	namespace detail
+	{
+		_GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(-)
+		_GLM_SWIZZLE_SCALAR_BINARY_OPERATOR_IMPLEMENTATION(*)
+        
+		_GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(+)
+		_GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(-)
+		_GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(*)
+		_GLM_SWIZZLE_VECTOR_BINARY_OPERATOR_IMPLEMENTATION(/)
+	}
+
+    //
+    // Swizzles are distinct types from the unswizzled type.  The below macros will
+    // provide template specializations for the swizzle types for the given functions
+    // so that the compiler does not have any ambiguity to choosing how to handle
+    // the function.
+    //
+    // The alternative is to use the operator()() when calling the function in order
+    // to explicitly convert the swizzled type to the unswizzled type.
+    //
+
+    //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type,    abs);
+    //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type,    acos);
+    //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type,    acosh);
+    //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type,    all);
+    //_GLM_SWIZZLE_FUNCTION_1_ARGS(vec_type,    any);
+    
+    //_GLM_SWIZZLE_FUNCTION_2_ARGS(value_type,  dot);
+    //_GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type,    cross);
+    //_GLM_SWIZZLE_FUNCTION_2_ARGS(vec_type,    step);    
+    //_GLM_SWIZZLE_FUNCTION_2_ARGS_SCALAR(vec_type, mix);
+}
+
 #define _GLM_SWIZZLE2_2_MEMBERS(T,P,E0,E1) \
-    struct { glm::detail::swizzle2<T,P,0,0> E0 ## E0; }; \
-    struct { glm::detail::swizzle2<T,P,0,1> E0 ## E1; }; \
-    struct { glm::detail::swizzle2<T,P,1,0> E1 ## E0; }; \
-    struct { glm::detail::swizzle2<T,P,1,1> E1 ## E1; }; 
+	struct { glm::detail::swizzle<2,T,P,0,0,-1,-2> E0 ## E0; }; \
+	struct { glm::detail::swizzle<2,T,P,0,1,-1,-2> E0 ## E1; }; \
+	struct { glm::detail::swizzle<2,T,P,1,0,-1,-2> E1 ## E0; }; \
+	struct { glm::detail::swizzle<2,T,P,1,1,-1,-2> E1 ## E1; }; 
 
 #define _GLM_SWIZZLE2_3_MEMBERS(T,P2,E0,E1) \
-    struct { glm::detail::swizzle2_3<T,P2,0,0,0> E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle2_3<T,P2,0,0,1> E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle2_3<T,P2,0,1,0> E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle2_3<T,P2,0,1,1> E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle2_3<T,P2,1,0,0> E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle2_3<T,P2,1,0,1> E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle2_3<T,P2,1,1,0> E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle2_3<T,P2,1,1,1> E1 ## E1 ## E1; };  
-
+	struct { glm::detail::swizzle<3,T,P2,0,0,0,-1> E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P2,0,0,1,-1> E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P2,0,1,0,-1> E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P2,0,1,1,-1> E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P2,1,0,0,-1> E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P2,1,0,1,-1> E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P2,1,1,0,-1> E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P2,1,1,1,-1> E1 ## E1 ## E1; };  
 
-#define _GLM_SWIZZLE3_3_MEMBERS(T,P,E0,E1,E2) \
-    struct { glm::detail::swizzle3<T,P,0,0,0> E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3<T,P,0,0,1> E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3<T,P,0,0,2> E0 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3<T,P,0,1,0> E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3<T,P,0,1,1> E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3<T,P,0,1,2> E0 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3<T,P,0,2,0> E0 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3<T,P,0,2,1> E0 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3<T,P,0,2,2> E0 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle3<T,P,1,0,0> E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3<T,P,1,0,1> E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3<T,P,1,0,2> E1 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3<T,P,1,1,0> E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3<T,P,1,1,1> E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3<T,P,1,1,2> E1 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3<T,P,1,2,0> E1 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3<T,P,1,2,1> E1 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3<T,P,1,2,2> E1 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle3<T,P,2,0,0> E2 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3<T,P,2,0,1> E2 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3<T,P,2,0,2> E2 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3<T,P,2,1,0> E2 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3<T,P,2,1,1> E2 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3<T,P,2,1,2> E2 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3<T,P,2,2,0> E2 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3<T,P,2,2,1> E2 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3<T,P,2,2,2> E2 ## E2 ## E2; };
+#define _GLM_SWIZZLE2_4_MEMBERS(T,P2,E0,E1) \
+	struct { glm::detail::swizzle<4,T,P2,0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,1,1> E1 ## E1 ## E1 ## E1; };  
 
 #define _GLM_SWIZZLE3_2_MEMBERS(T,P2,E0,E1,E2) \
-    struct { glm::detail::swizzle3_2<T,P2,0,0> E0 ## E0; }; \
-    struct { glm::detail::swizzle3_2<T,P2,0,1> E0 ## E1; }; \
-    struct { glm::detail::swizzle3_2<T,P2,0,2> E0 ## E2; }; \
-    struct { glm::detail::swizzle3_2<T,P2,1,0> E1 ## E0; }; \
-    struct { glm::detail::swizzle3_2<T,P2,1,1> E1 ## E1; }; \
-    struct { glm::detail::swizzle3_2<T,P2,1,2> E1 ## E2; }; \
-    struct { glm::detail::swizzle3_2<T,P2,2,0> E2 ## E0; }; \
-    struct { glm::detail::swizzle3_2<T,P2,2,1> E2 ## E1; }; \
-    struct { glm::detail::swizzle3_2<T,P2,2,2> E2 ## E2; }; 
-
-#define _GLM_SWIZZLE3_4_MEMBERS(T,P2,E0,E1,E2) \
-    struct { glm::detail::swizzle3_4<T,P2,0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,0,0,2> E0 ## E0 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,0,1,2> E0 ## E0 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,0,2,0> E0 ## E0 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,0,2,1> E0 ## E0 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,0,2,2> E0 ## E0 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,1,0,2> E0 ## E1 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,1,1,2> E0 ## E1 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,1,2,0> E0 ## E1 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,1,2,1> E0 ## E1 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,1,2,2> E0 ## E1 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,2,0,0> E0 ## E2 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,2,0,1> E0 ## E2 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,2,0,2> E0 ## E2 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,2,1,0> E0 ## E2 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,2,1,1> E0 ## E2 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,2,1,2> E0 ## E2 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,2,2,0> E0 ## E2 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,2,2,1> E0 ## E2 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,0,2,2,2> E0 ## E2 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle3_4<T,P2,1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,0,0,2> E1 ## E0 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,0,1,2> E1 ## E0 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,0,2,0> E1 ## E0 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,0,2,1> E1 ## E0 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,0,2,2> E1 ## E0 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,1,0,2> E1 ## E1 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,1,1,1> E1 ## E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,1,1,2> E1 ## E1 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,1,2,0> E1 ## E1 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,1,2,1> E1 ## E1 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,1,2,2> E1 ## E1 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,2,0,0> E1 ## E2 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,2,0,1> E1 ## E2 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,2,0,2> E1 ## E2 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,2,1,0> E1 ## E2 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,2,1,1> E1 ## E2 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,2,1,2> E1 ## E2 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,2,2,0> E1 ## E2 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,2,2,1> E1 ## E2 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,1,2,2,2> E1 ## E2 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle3_4<T,P2,2,0,0,0> E2 ## E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,0,0,1> E2 ## E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,0,0,2> E2 ## E0 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,0,1,0> E2 ## E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,0,1,1> E2 ## E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,0,1,2> E2 ## E0 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,0,2,0> E2 ## E0 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,0,2,1> E2 ## E0 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,0,2,2> E2 ## E0 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,1,0,0> E2 ## E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,1,0,1> E2 ## E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,1,0,2> E2 ## E1 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,1,1,0> E2 ## E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,1,1,1> E2 ## E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,1,1,2> E2 ## E1 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,1,2,0> E2 ## E1 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,1,2,1> E2 ## E1 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,1,2,2> E2 ## E1 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,2,0,0> E2 ## E2 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,2,0,1> E2 ## E2 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,2,0,2> E2 ## E2 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,2,1,0> E2 ## E2 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,2,1,1> E2 ## E2 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,2,1,2> E2 ## E2 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,2,2,0> E2 ## E2 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,2,2,1> E2 ## E2 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle3_4<T,P2,2,2,2,2> E2 ## E2 ## E2 ## E2; }; \
-
+	struct { glm::detail::swizzle<2,T,P2,0,0,-1,-2> E0 ## E0; }; \
+	struct { glm::detail::swizzle<2,T,P2,0,1,-1,-2> E0 ## E1; }; \
+	struct { glm::detail::swizzle<2,T,P2,0,2,-1,-2> E0 ## E2; }; \
+	struct { glm::detail::swizzle<2,T,P2,1,0,-1,-2> E1 ## E0; }; \
+	struct { glm::detail::swizzle<2,T,P2,1,1,-1,-2> E1 ## E1; }; \
+	struct { glm::detail::swizzle<2,T,P2,1,2,-1,-2> E1 ## E2; }; \
+	struct { glm::detail::swizzle<2,T,P2,2,0,-1,-2> E2 ## E0; }; \
+	struct { glm::detail::swizzle<2,T,P2,2,1,-1,-2> E2 ## E1; }; \
+	struct { glm::detail::swizzle<2,T,P2,2,2,-1,-2> E2 ## E2; }; 
 
-#define _GLM_SWIZZLE2_4_MEMBERS(T,P2,E0,E1) \
-    struct { glm::detail::swizzle2_4<T,P2,0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle2_4<T,P2,0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle2_4<T,P2,0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle2_4<T,P2,0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle2_4<T,P2,0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle2_4<T,P2,0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle2_4<T,P2,0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle2_4<T,P2,0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle2_4<T,P2,1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle2_4<T,P2,1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle2_4<T,P2,1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle2_4<T,P2,1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle2_4<T,P2,1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle2_4<T,P2,1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle2_4<T,P2,1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle2_4<T,P2,1,1,1,1> E1 ## E1 ## E1 ## E1; };  
+#define _GLM_SWIZZLE3_3_MEMBERS(T,P,E0,E1,E2) \
+	struct { glm::detail::swizzle<3,T,P,0,0,0,-1> E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,0,0,1,-1> E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,0,0,2,-1> E0 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,0,1,0,-1> E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,0,1,1,-1> E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,0,1,2,-1> E0 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,0,2,0,-1> E0 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,0,2,1,-1> E0 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,0,2,2,-1> E0 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,1,0,0,-1> E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,1,0,1,-1> E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,1,0,2,-1> E1 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,1,1,0,-1> E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,1,1,1,-1> E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,1,1,2,-1> E1 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,1,2,0,-1> E1 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,1,2,1,-1> E1 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,1,2,2,-1> E1 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,2,0,0,-1> E2 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,2,0,1,-1> E2 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,2,0,2,-1> E2 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,2,1,0,-1> E2 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,2,1,1,-1> E2 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,2,1,2,-1> E2 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,2,2,0,-1> E2 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,2,2,1,-1> E2 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,2,2,2,-1> E2 ## E2 ## E2; };
 
+#define _GLM_SWIZZLE3_4_MEMBERS(T,P2,E0,E1,E2) \
+	struct { glm::detail::swizzle<4,T,P2,0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,0,2> E0 ## E0 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,1,2> E0 ## E0 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,2,0> E0 ## E0 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,2,1> E0 ## E0 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,0,2,2> E0 ## E0 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,0,2> E0 ## E1 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,1,2> E0 ## E1 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,2,0> E0 ## E1 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,2,1> E0 ## E1 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,1,2,2> E0 ## E1 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,2,0,0> E0 ## E2 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,2,0,1> E0 ## E2 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,2,0,2> E0 ## E2 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,2,1,0> E0 ## E2 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,2,1,1> E0 ## E2 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,2,1,2> E0 ## E2 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,2,2,0> E0 ## E2 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,2,2,1> E0 ## E2 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,0,2,2,2> E0 ## E2 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,0,2> E1 ## E0 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,1,2> E1 ## E0 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,2,0> E1 ## E0 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,2,1> E1 ## E0 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,0,2,2> E1 ## E0 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,0,2> E1 ## E1 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,1,1> E1 ## E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,1,2> E1 ## E1 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,2,0> E1 ## E1 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,2,1> E1 ## E1 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,1,2,2> E1 ## E1 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,2,0,0> E1 ## E2 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,2,0,1> E1 ## E2 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,2,0,2> E1 ## E2 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,2,1,0> E1 ## E2 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,2,1,1> E1 ## E2 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,2,1,2> E1 ## E2 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,2,2,0> E1 ## E2 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,2,2,1> E1 ## E2 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,1,2,2,2> E1 ## E2 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,0,0,0> E2 ## E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,0,0,1> E2 ## E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,0,0,2> E2 ## E0 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,0,1,0> E2 ## E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,0,1,1> E2 ## E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,0,1,2> E2 ## E0 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,0,2,0> E2 ## E0 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,0,2,1> E2 ## E0 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,0,2,2> E2 ## E0 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,1,0,0> E2 ## E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,1,0,1> E2 ## E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,1,0,2> E2 ## E1 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,1,1,0> E2 ## E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,1,1,1> E2 ## E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,1,1,2> E2 ## E1 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,1,2,0> E2 ## E1 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,1,2,1> E2 ## E1 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,1,2,2> E2 ## E1 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,2,0,0> E2 ## E2 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,2,0,1> E2 ## E2 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,2,0,2> E2 ## E2 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,2,1,0> E2 ## E2 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,2,1,1> E2 ## E2 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,2,1,2> E2 ## E2 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,2,2,0> E2 ## E2 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,2,2,1> E2 ## E2 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P2,2,2,2,2> E2 ## E2 ## E2 ## E2; }; 
 
 #define _GLM_SWIZZLE4_2_MEMBERS(T,P,E0,E1,E2,E3) \
-    struct { glm::detail::swizzle4_2<T,P,0,0> E0 ## E0; }; \
-    struct { glm::detail::swizzle4_2<T,P,0,1> E0 ## E1; }; \
-    struct { glm::detail::swizzle4_2<T,P,0,2> E0 ## E2; }; \
-    struct { glm::detail::swizzle4_2<T,P,0,3> E0 ## E3; }; \
-    struct { glm::detail::swizzle4_2<T,P,1,0> E1 ## E0; }; \
-    struct { glm::detail::swizzle4_2<T,P,1,1> E1 ## E1; }; \
-    struct { glm::detail::swizzle4_2<T,P,1,2> E1 ## E2; }; \
-    struct { glm::detail::swizzle4_2<T,P,1,3> E1 ## E3; }; \
-    struct { glm::detail::swizzle4_2<T,P,2,0> E2 ## E0; }; \
-    struct { glm::detail::swizzle4_2<T,P,2,1> E2 ## E1; }; \
-    struct { glm::detail::swizzle4_2<T,P,2,2> E2 ## E2; }; \
-    struct { glm::detail::swizzle4_2<T,P,2,3> E2 ## E3; }; \
-    struct { glm::detail::swizzle4_2<T,P,3,0> E3 ## E0; }; \
-    struct { glm::detail::swizzle4_2<T,P,3,1> E3 ## E1; }; \
-    struct { glm::detail::swizzle4_2<T,P,3,2> E3 ## E2; }; \
-    struct { glm::detail::swizzle4_2<T,P,3,3> E3 ## E3; }; 
+	struct { glm::detail::swizzle<2,T,P,0,0,-1,-2> E0 ## E0; }; \
+	struct { glm::detail::swizzle<2,T,P,0,1,-1,-2> E0 ## E1; }; \
+	struct { glm::detail::swizzle<2,T,P,0,2,-1,-2> E0 ## E2; }; \
+	struct { glm::detail::swizzle<2,T,P,0,3,-1,-2> E0 ## E3; }; \
+	struct { glm::detail::swizzle<2,T,P,1,0,-1,-2> E1 ## E0; }; \
+	struct { glm::detail::swizzle<2,T,P,1,1,-1,-2> E1 ## E1; }; \
+	struct { glm::detail::swizzle<2,T,P,1,2,-1,-2> E1 ## E2; }; \
+	struct { glm::detail::swizzle<2,T,P,1,3,-1,-2> E1 ## E3; }; \
+	struct { glm::detail::swizzle<2,T,P,2,0,-1,-2> E2 ## E0; }; \
+	struct { glm::detail::swizzle<2,T,P,2,1,-1,-2> E2 ## E1; }; \
+	struct { glm::detail::swizzle<2,T,P,2,2,-1,-2> E2 ## E2; }; \
+	struct { glm::detail::swizzle<2,T,P,2,3,-1,-2> E2 ## E3; }; \
+	struct { glm::detail::swizzle<2,T,P,3,0,-1,-2> E3 ## E0; }; \
+	struct { glm::detail::swizzle<2,T,P,3,1,-1,-2> E3 ## E1; }; \
+	struct { glm::detail::swizzle<2,T,P,3,2,-1,-2> E3 ## E2; }; \
+	struct { glm::detail::swizzle<2,T,P,3,3,-1,-2> E3 ## E3; }; 
 
 #define _GLM_SWIZZLE4_3_MEMBERS(T,P,E0,E1,E2,E3) \
-    struct { glm::detail::swizzle4_3<T,P,0,0,0> E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,0,1> E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,0,2> E0 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,0,3> E0 ## E0 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,1,0> E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,1,1> E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,1,2> E0 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,1,3> E0 ## E1 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,2,0> E0 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,2,1> E0 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,2,2> E0 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,2,3> E0 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,3,0> E0 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,3,1> E0 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,3,2> E0 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,0,3,3> E0 ## E3 ## E3; }; \
-    \
-    struct { glm::detail::swizzle4_3<T,P,1,0,0> E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,0,1> E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,0,2> E1 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,0,3> E1 ## E0 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,1,0> E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,1,1> E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,1,2> E1 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,1,3> E1 ## E1 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,2,0> E1 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,2,1> E1 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,2,2> E1 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,2,3> E1 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,3,0> E1 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,3,1> E1 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,3,2> E1 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,1,3,3> E1 ## E3 ## E3; }; \
-    \
-    struct { glm::detail::swizzle4_3<T,P,2,0,0> E2 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,0,1> E2 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,0,2> E2 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,0,3> E2 ## E0 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,1,0> E2 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,1,1> E2 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,1,2> E2 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,1,3> E2 ## E1 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,2,0> E2 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,2,1> E2 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,2,2> E2 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,2,3> E2 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,3,0> E2 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,3,1> E2 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,3,2> E2 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,2,3,3> E2 ## E3 ## E3; }; \
-    \
-    struct { glm::detail::swizzle4_3<T,P,3,0,0> E3 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,0,1> E3 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,0,2> E3 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,0,3> E3 ## E0 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,1,0> E3 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,1,1> E3 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,1,2> E3 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,1,3> E3 ## E1 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,2,0> E3 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,2,1> E3 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,2,2> E3 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,2,3> E3 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,3,0> E3 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,3,1> E3 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,3,2> E3 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4_3<T,P,3,3,3> E3 ## E3 ## E3; };  
+	struct { glm::detail::swizzle<3,T,P,0,0,0,-1> E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,0,0,1,-1> E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,0,0,2,-1> E0 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,0,0,3,-1> E0 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,0,1,0,-1> E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,0,1,1,-1> E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,0,1,2,-1> E0 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,0,1,3,-1> E0 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,0,2,0,-1> E0 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,0,2,1,-1> E0 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,0,2,2,-1> E0 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,0,2,3,-1> E0 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,0,3,0,-1> E0 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,0,3,1,-1> E0 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,0,3,2,-1> E0 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,0,3,3,-1> E0 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,1,0,0,-1> E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,1,0,1,-1> E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,1,0,2,-1> E1 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,1,0,3,-1> E1 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,1,1,0,-1> E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,1,1,1,-1> E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,1,1,2,-1> E1 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,1,1,3,-1> E1 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,1,2,0,-1> E1 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,1,2,1,-1> E1 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,1,2,2,-1> E1 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,1,2,3,-1> E1 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,1,3,0,-1> E1 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,1,3,1,-1> E1 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,1,3,2,-1> E1 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,1,3,3,-1> E1 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,2,0,0,-1> E2 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,2,0,1,-1> E2 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,2,0,2,-1> E2 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,2,0,3,-1> E2 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,2,1,0,-1> E2 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,2,1,1,-1> E2 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,2,1,2,-1> E2 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,2,1,3,-1> E2 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,2,2,0,-1> E2 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,2,2,1,-1> E2 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,2,2,2,-1> E2 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,2,2,3,-1> E2 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,2,3,0,-1> E2 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,2,3,1,-1> E2 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,2,3,2,-1> E2 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,2,3,3,-1> E2 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,3,0,0,-1> E3 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,3,0,1,-1> E3 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,3,0,2,-1> E3 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,3,0,3,-1> E3 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,3,1,0,-1> E3 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,3,1,1,-1> E3 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,3,1,2,-1> E3 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,3,1,3,-1> E3 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,3,2,0,-1> E3 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,3,2,1,-1> E3 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,3,2,2,-1> E3 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,3,2,3,-1> E3 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<3,T,P,3,3,0,-1> E3 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<3,T,P,3,3,1,-1> E3 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<3,T,P,3,3,2,-1> E3 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<3,T,P,3,3,3,-1> E3 ## E3 ## E3; };  
     
 
 #define _GLM_SWIZZLE4_4_MEMBERS(T,P,E0,E1,E2,E3) \
-    struct { glm::detail::swizzle4<T,P,0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,0,2> E0 ## E0 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,1,2> E0 ## E0 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,2,0> E0 ## E0 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,2,1> E0 ## E0 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,2,2> E0 ## E0 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,0,2> E0 ## E1 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,1,2> E0 ## E1 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,2,0> E0 ## E1 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,2,1> E0 ## E1 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,2,2> E0 ## E1 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,0,2,0,0> E0 ## E2 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,0,1> E0 ## E2 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,0,2> E0 ## E2 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,1,0> E0 ## E2 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,1,1> E0 ## E2 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,1,2> E0 ## E2 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,2,0> E0 ## E2 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,2,1> E0 ## E2 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,2,2> E0 ## E2 ## E2 ## E2; }; \
-    \
-    \
-    struct { glm::detail::swizzle4<T,P,1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,0,2> E1 ## E0 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,1,2> E1 ## E0 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,2,0> E1 ## E0 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,2,1> E1 ## E0 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,2,2> E1 ## E0 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,0,2> E1 ## E1 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,1,1> E1 ## E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,1,2> E1 ## E1 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,2,0> E1 ## E1 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,2,1> E1 ## E1 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,2,2> E1 ## E1 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,1,2,0,0> E1 ## E2 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,0,1> E1 ## E2 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,0,2> E1 ## E2 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,1,0> E1 ## E2 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,1,1> E1 ## E2 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,1,2> E1 ## E2 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,2,0> E1 ## E2 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,2,1> E1 ## E2 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,2,2> E1 ## E2 ## E2 ## E2; }; \
-    \
-    \
-    struct { glm::detail::swizzle4<T,P,2,0,0,0> E2 ## E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,0,1> E2 ## E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,0,2> E2 ## E0 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,1,0> E2 ## E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,1,1> E2 ## E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,1,2> E2 ## E0 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,2,0> E2 ## E0 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,2,1> E2 ## E0 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,2,2> E2 ## E0 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,2,1,0,0> E2 ## E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,0,1> E2 ## E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,0,2> E2 ## E1 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,1,0> E2 ## E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,1,1> E2 ## E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,1,2> E2 ## E1 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,2,0> E2 ## E1 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,2,1> E2 ## E1 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,2,2> E2 ## E1 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,2,2,0,0> E2 ## E2 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,0,1> E2 ## E2 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,0,2> E2 ## E2 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,1,0> E2 ## E2 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,1,1> E2 ## E2 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,1,2> E2 ## E2 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,2,0> E2 ## E2 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,2,1> E2 ## E2 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,2,2> E2 ## E2 ## E2 ## E2; }; \
-    \
-    \
-    struct { glm::detail::swizzle4<T,P,3,0,0,0> E3 ## E0 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,0,1> E3 ## E0 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,0,2> E3 ## E0 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,1,0> E3 ## E0 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,1,1> E3 ## E0 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,1,2> E3 ## E0 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,2,0> E3 ## E0 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,2,1> E3 ## E0 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,2,2> E3 ## E0 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,3,1,0,0> E3 ## E1 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,0,1> E3 ## E1 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,0,2> E3 ## E1 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,1,0> E3 ## E1 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,1,1> E3 ## E1 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,1,2> E3 ## E1 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,2,0> E3 ## E1 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,2,1> E3 ## E1 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,2,2> E3 ## E1 ## E2 ## E2; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,3,2,0,0> E3 ## E2 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,0,1> E3 ## E2 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,0,2> E3 ## E2 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,1,0> E3 ## E2 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,1,1> E3 ## E2 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,1,2> E3 ## E2 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,2,0> E3 ## E2 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,2,1> E3 ## E2 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,2,2> E3 ## E2 ## E2 ## E2; }; 
-
-
-
-
+	struct { glm::detail::swizzle<4,T,P,0,0,0,0> E0 ## E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,0,1> E0 ## E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,0,2> E0 ## E0 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,0,3> E0 ## E0 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,1,0> E0 ## E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,1,1> E0 ## E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,1,2> E0 ## E0 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,1,3> E0 ## E0 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,2,0> E0 ## E0 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,2,1> E0 ## E0 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,2,2> E0 ## E0 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,2,3> E0 ## E0 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,3,0> E0 ## E0 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,3,1> E0 ## E0 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,3,2> E0 ## E0 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,0,3,3> E0 ## E0 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,0,0> E0 ## E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,0,1> E0 ## E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,0,2> E0 ## E1 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,0,3> E0 ## E1 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,1,0> E0 ## E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,1,1> E0 ## E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,1,2> E0 ## E1 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,1,3> E0 ## E1 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,2,0> E0 ## E1 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,2,1> E0 ## E1 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,2,2> E0 ## E1 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,2,3> E0 ## E1 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,3,0> E0 ## E1 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,3,1> E0 ## E1 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,3,2> E0 ## E1 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,1,3,3> E0 ## E1 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,0,0> E0 ## E2 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,0,1> E0 ## E2 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,0,2> E0 ## E2 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,0,3> E0 ## E2 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,1,0> E0 ## E2 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,1,1> E0 ## E2 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,1,2> E0 ## E2 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,1,3> E0 ## E2 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,2,0> E0 ## E2 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,2,1> E0 ## E2 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,2,2> E0 ## E2 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,2,3> E0 ## E2 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,3,0> E0 ## E2 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,3,1> E0 ## E2 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,3,2> E0 ## E2 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,0,2,3,3> E0 ## E2 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,0,0> E1 ## E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,0,1> E1 ## E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,0,2> E1 ## E0 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,0,3> E1 ## E0 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,1,0> E1 ## E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,1,1> E1 ## E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,1,2> E1 ## E0 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,1,3> E1 ## E0 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,2,0> E1 ## E0 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,2,1> E1 ## E0 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,2,2> E1 ## E0 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,2,3> E1 ## E0 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,3,0> E1 ## E0 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,3,1> E1 ## E0 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,3,2> E1 ## E0 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,0,3,3> E1 ## E0 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,0,0> E1 ## E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,0,1> E1 ## E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,0,2> E1 ## E1 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,0,3> E1 ## E1 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,1,0> E1 ## E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,1,1> E1 ## E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,1,2> E1 ## E1 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,1,3> E1 ## E1 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,2,0> E1 ## E1 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,2,1> E1 ## E1 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,2,2> E1 ## E1 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,2,3> E1 ## E1 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,3,0> E1 ## E1 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,3,1> E1 ## E1 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,3,2> E1 ## E1 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,1,3,3> E1 ## E1 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,0,0> E1 ## E2 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,0,1> E1 ## E2 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,0,2> E1 ## E2 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,0,3> E1 ## E2 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,1,0> E1 ## E2 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,1,1> E1 ## E2 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,1,2> E1 ## E2 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,1,3> E1 ## E2 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,2,0> E1 ## E2 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,2,1> E1 ## E2 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,2,2> E1 ## E2 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,2,3> E1 ## E2 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,3,0> E1 ## E2 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,3,1> E1 ## E2 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,3,2> E1 ## E2 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,2,3,3> E1 ## E2 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,0,0> E1 ## E3 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,0,1> E1 ## E3 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,0,2> E1 ## E3 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,0,3> E1 ## E3 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,1,0> E1 ## E3 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,1,1> E1 ## E3 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,1,2> E1 ## E3 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,1,3> E1 ## E3 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,2,0> E1 ## E3 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,2,1> E1 ## E3 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,2,2> E1 ## E3 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,2,3> E1 ## E3 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,3,0> E1 ## E3 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,3,1> E1 ## E3 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,3,2> E1 ## E3 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,1,3,3,3> E1 ## E3 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,0,0> E2 ## E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,0,1> E2 ## E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,0,2> E2 ## E0 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,0,3> E2 ## E0 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,1,0> E2 ## E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,1,1> E2 ## E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,1,2> E2 ## E0 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,1,3> E2 ## E0 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,2,0> E2 ## E0 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,2,1> E2 ## E0 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,2,2> E2 ## E0 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,2,3> E2 ## E0 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,3,0> E2 ## E0 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,3,1> E2 ## E0 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,3,2> E2 ## E0 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,0,3,3> E2 ## E0 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,0,0> E2 ## E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,0,1> E2 ## E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,0,2> E2 ## E1 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,0,3> E2 ## E1 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,1,0> E2 ## E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,1,1> E2 ## E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,1,2> E2 ## E1 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,1,3> E2 ## E1 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,2,0> E2 ## E1 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,2,1> E2 ## E1 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,2,2> E2 ## E1 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,2,3> E2 ## E1 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,3,0> E2 ## E1 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,3,1> E2 ## E1 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,3,2> E2 ## E1 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,1,3,3> E2 ## E1 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,0,0> E2 ## E2 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,0,1> E2 ## E2 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,0,2> E2 ## E2 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,0,3> E2 ## E2 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,1,0> E2 ## E2 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,1,1> E2 ## E2 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,1,2> E2 ## E2 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,1,3> E2 ## E2 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,2,0> E2 ## E2 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,2,1> E2 ## E2 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,2,2> E2 ## E2 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,2,3> E2 ## E2 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,3,0> E2 ## E2 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,3,1> E2 ## E2 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,3,2> E2 ## E2 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,2,3,3> E2 ## E2 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,0,0> E2 ## E3 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,0,1> E2 ## E3 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,0,2> E2 ## E3 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,0,3> E2 ## E3 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,1,0> E2 ## E3 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,1,1> E2 ## E3 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,1,2> E2 ## E3 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,1,3> E2 ## E3 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,2,0> E2 ## E3 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,2,1> E2 ## E3 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,2,2> E2 ## E3 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,2,3> E2 ## E3 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,3,0> E2 ## E3 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,3,1> E2 ## E3 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,3,2> E2 ## E3 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,2,3,3,3> E2 ## E3 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,0,0> E3 ## E0 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,0,1> E3 ## E0 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,0,2> E3 ## E0 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,0,3> E3 ## E0 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,1,0> E3 ## E0 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,1,1> E3 ## E0 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,1,2> E3 ## E0 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,1,3> E3 ## E0 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,2,0> E3 ## E0 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,2,1> E3 ## E0 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,2,2> E3 ## E0 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,2,3> E3 ## E0 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,3,0> E3 ## E0 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,3,1> E3 ## E0 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,3,2> E3 ## E0 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,0,3,3> E3 ## E0 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,0,0> E3 ## E1 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,0,1> E3 ## E1 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,0,2> E3 ## E1 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,0,3> E3 ## E1 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,1,0> E3 ## E1 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,1,1> E3 ## E1 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,1,2> E3 ## E1 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,1,3> E3 ## E1 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,2,0> E3 ## E1 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,2,1> E3 ## E1 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,2,2> E3 ## E1 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,2,3> E3 ## E1 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,3,0> E3 ## E1 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,3,1> E3 ## E1 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,3,2> E3 ## E1 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,1,3,3> E3 ## E1 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,0,0> E3 ## E2 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,0,1> E3 ## E2 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,0,2> E3 ## E2 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,0,3> E3 ## E2 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,1,0> E3 ## E2 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,1,1> E3 ## E2 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,1,2> E3 ## E2 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,1,3> E3 ## E2 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,2,0> E3 ## E2 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,2,1> E3 ## E2 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,2,2> E3 ## E2 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,2,3> E3 ## E2 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,3,0> E3 ## E2 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,3,1> E3 ## E2 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,3,2> E3 ## E2 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,2,3,3> E3 ## E2 ## E3 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,0,0> E3 ## E3 ## E0 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,0,1> E3 ## E3 ## E0 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,0,2> E3 ## E3 ## E0 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,0,3> E3 ## E3 ## E0 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,1,0> E3 ## E3 ## E1 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,1,1> E3 ## E3 ## E1 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,1,2> E3 ## E3 ## E1 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,1,3> E3 ## E3 ## E1 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,2,0> E3 ## E3 ## E2 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,2,1> E3 ## E3 ## E2 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,2,2> E3 ## E3 ## E2 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,2,3> E3 ## E3 ## E2 ## E3; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,3,0> E3 ## E3 ## E3 ## E0; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,3,1> E3 ## E3 ## E3 ## E1; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,3,2> E3 ## E3 ## E3 ## E2; }; \
+	struct { glm::detail::swizzle<4,T,P,3,3,3,3> E3 ## E3 ## E3 ## E3; }; 
 
 #if(defined(GLM_SWIZZLE_XYZW) || defined(GLM_SWIZZLE))
 

+ 1 - 0
glm/core/func_geometric.inl

@@ -132,6 +132,7 @@ namespace glm
 	(
 		genType const & x, 
 		genType const & y
+        
 	)
 	{
 		GLM_STATIC_ASSERT(detail::type<genType>::is_float, "'dot' only accept floating-point inputs");

+ 6 - 0
glm/core/type_vec2.hpp

@@ -114,6 +114,12 @@ namespace detail
 
 		tvec2(tref2<T> const & r);
 
+        template <int E0, int E1>
+        GLM_FUNC_DECL tvec2(const glm::detail::swizzle<2,T,tvec2<T>,E0,E1,-1,-2>& that)
+        {
+            *this = that();
+        }
+
 		//////////////////////////////////////
 		// Convertion constructors
 

+ 8 - 2
glm/core/type_vec3.hpp

@@ -64,7 +64,7 @@ namespace detail
 
 #	if(GLM_COMPONENT == GLM_COMPONENT_ONLY_XYZW)
 		value_type x, y, z;
-#	elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT)
+#	elif(GLM_COMPONENT == GLM_COMPONENT_MS_EXT || GLM_LANG == GLM_LANG_CXX0X)
 		union 
 		{
             _GLM_SWIZZLE3_2_MEMBERS(value_type,glm::detail::tvec2<value_type>,x,y,z)
@@ -80,7 +80,7 @@ namespace detail
 			struct{value_type r, g, b;};
 			struct{value_type s, t, p;};
 			struct{value_type x, y, z;};
-        };
+		};
 #	else//(GLM_COMPONENT == GLM_COMPONENT_GLSL_NAMES)
 		union {value_type x, r, s;};
 		union {value_type y, g, t;};
@@ -152,6 +152,12 @@ namespace detail
 		template <typename A, typename B> 
 		GLM_FUNC_DECL explicit tvec3(A const & s, tref2<B> 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)
+        {
+            *this = that();
+        }
+
 		//////////////////////////////////////
 		// Unary arithmetic operators
 

+ 6 - 0
glm/core/type_vec4.hpp

@@ -153,6 +153,12 @@ namespace detail
 		template <typename U> 
 		GLM_FUNC_DECL explicit tvec4(tvec4<U> 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)
+        {
+            *this = that();
+        }
+
 		//////////////////////////////////////
 		// Swizzle constructors
 

+ 106 - 37
test/core/core_type_vec3.cpp

@@ -247,30 +247,20 @@ int test_vec3_swizzle3_3()
     glm::vec3 v(1, 2, 3);
     glm::vec3 u;
     
-    u.xyz = v.xyz;
-    Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
+    u = v;          Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
     
-    u = v.xyz;
-    Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
-    u = v.zyx;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
-    u.zyx = v;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
-    
-    u = v.rgb;
-    Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
-    u = v.bgr;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
-    u.bgr = v;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
-
-    u = v.stp;
-    Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
-    u = v.pts;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
-    u.pts = v;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+    u = v.xyz;      Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
+    u = v.zyx;      Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+    u.zyx = v;      Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
     
+    u = v.rgb;      Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
+    u = v.bgr;      Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+    u.bgr = v;      Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+
+    u = v.stp;      Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
+    u = v.pts;      Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+    u.pts = v;      Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+   
     return Error;
 }
 
@@ -284,34 +274,111 @@ int test_vec3_swizzle_half()
     glm::hvec3 v(a1, b1, c1);
     glm::hvec3 u;
 
-    float c = v.x;
-    float d = v.y;
     u = v;
 
-    float a = u.x;
-    float b = u.y;
-    Error += (u.x == glm::half(1.0f) && u.y == glm::half(2.0f) && u.z == glm::half(3.0f)) ? 0 : 1;
+    Error += (u.x.toFloat() == 1.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 3.0f) ? 0 : 1;
     
-    /*u = v.xyz;
-    Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
+    u = v.xyz;
+    Error += (u.x.toFloat() == 1.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 3.0f) ? 0 : 1;
     u = v.zyx;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+    Error += (u.x.toFloat() == 3.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 1.0f) ? 0 : 1;
     u.zyx = v;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+    Error += (u.x.toFloat() == 3.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 1.0f) ? 0 : 1;
     
     u = v.rgb;
-    Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
+    Error += (u.x.toFloat() == 1.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 3.0f) ? 0 : 1;
     u = v.bgr;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+    Error += (u.x.toFloat() == 3.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 1.0f) ? 0 : 1;
     u.bgr = v;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+    Error += (u.x.toFloat() == 3.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 1.0f) ? 0 : 1;
 
     u = v.stp;
-    Error += (u.x == 1.0f && u.y == 2.0f && u.z == 3.0f) ? 0 : 1;
+    Error += (u.x.toFloat() == 1.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 3.0f) ? 0 : 1;
     u = v.pts;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;
+    Error += (u.x.toFloat() == 3.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 1.0f) ? 0 : 1;
     u.pts = v;
-    Error += (u.x == 3.0f && u.y == 2.0f && u.z == 1.0f) ? 0 : 1;*/
+    Error += (u.x.toFloat() == 3.0f && u.y.toFloat() == 2.0f && u.z.toFloat() == 1.0f) ? 0 : 1;
+
+    return Error;
+}
+
+int test_vec3_swizzle_operators()
+{
+    int Error = 0;
+
+    glm::vec3 q, u, v;
+
+    u = glm::vec3(1, 2, 3);
+    v = glm::vec3(10, 20, 30);
+
+    // Swizzle, swizzle binary operators
+    q = u.xyz + v.xyz;          Error += (q == (u + v)) ? 0 : 1;
+    q = (u.zyx + v.zyx).zyx;    Error += (q == (u + v)) ? 0 : 1;
+    q = (u.xyz - v.xyz);        Error += (q == (u - v)) ? 0 : 1;
+    q = (u.xyz * v.xyz);        Error += (q == (u * v)) ? 0 : 1;
+    q = (u.xxx * v.xxx);        Error += (q == glm::vec3(u.x * v.x)) ? 0 : 1;
+    q = (u.xyz / v.xyz);        Error += (q == (u / v)) ? 0 : 1;
+
+    // vec, swizzle binary operators
+    q = u + v.xyz;              Error += (q == (u + v)) ? 0 : 1;
+    q = (u - v.xyz);            Error += (q == (u - v)) ? 0 : 1;
+    q = (u * v.xyz);            Error += (q == (u * v)) ? 0 : 1;
+    q = (u * v.xxx);            Error += (q == v.x * u) ? 0 : 1;
+    q = (u / v.xyz);            Error += (q == (u / v)) ? 0 : 1;
+
+    // swizzle,vec binary operators
+    q = u.xyz + v;              Error += (q == (u + v)) ? 0 : 1;
+    q = (u.xyz - v);            Error += (q == (u - v)) ? 0 : 1;
+    q = (u.xyz * v);            Error += (q == (u * v)) ? 0 : 1;
+    q = (u.xxx * v);            Error += (q == u.x * v) ? 0 : 1;
+    q = (u.xyz / v);            Error += (q == (u / v)) ? 0 : 1;
+
+    // Compile errors
+    //q = (u.yz * v.xyz);
+    //q = (u * v.xy);
+
+    return Error;
+}
+
+int test_vec3_swizzle_functions()
+{
+    int Error = 0;
+
+    //
+    // NOTE: template functions cannot pick up the implicit conversion from
+    // a swizzle to the unswizzled type, therefore the operator() must be 
+    // used.  E.g.:
+    //
+    // glm::dot(u.xy, v.xy);        <--- Compile error
+    // glm::dot(u.xy(), v.xy());    <--- Compiles correctly
+    //
+
+    float r;
+
+    // vec2
+    glm::vec2 a(1, 2);
+    glm::vec2 b(10, 20);
+    r = glm::dot(a, b);                 Error += (int(r) == 50) ? 0 : 1;
+    r = glm::dot(a.xy(), b.xy());       Error += (int(r) == 50) ? 0 : 1;
+    r = glm::dot(a.xy(), b.yy());       Error += (int(r) == 60) ? 0 : 1;
+
+    // vec3
+    glm::vec3 q, u, v;
+    u = glm::vec3(1, 2, 3);
+    v = glm::vec3(10, 20, 30);
+    r = glm::dot(u, v);                 Error += (int(r) == 140) ? 0 : 1;
+    r = glm::dot(u.xyz(), v.zyz());     Error += (int(r) == 160) ? 0 : 1;
+    r = glm::dot(u, v.zyx());           Error += (int(r) == 100) ? 0 : 1;
+    r = glm::dot(u.xyz(), v);           Error += (int(r) == 140) ? 0 : 1;
+    r = glm::dot(u.xy(), v.xy());       Error += (int(r) == 50) ? 0 : 1;
+
+    // vec4
+    glm::vec4 s, t;
+    s = glm::vec4(1, 2, 3, 4);
+    t = glm::vec4(10, 20, 30, 40);
+    r = glm::dot(s, t);                 Error += (int(r) == 300) ? 0 : 1;
+    r = glm::dot(s.xyzw(), t.xyzw());   Error += (int(r) == 300) ? 0 : 1;
+    r = glm::dot(s.xyz(), t.xyz());     Error += (int(r) == 140) ? 0 : 1;
 
     return Error;
 }
@@ -354,6 +421,8 @@ int main()
     Error += test_vec3_swizzle3_3();
     Error += test_vec3_swizzle_half();
 	Error += test_vec3_swizzle_partial();
+    Error += test_vec3_swizzle_operators();
+    Error += test_vec3_swizzle_functions();
 	
 	return Error;
 }

+ 10 - 0
test/glm.cppcheck

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="1">
+    <root name="glm"/>
+    <includedir>
+        <dir name=".."/>
+    </includedir>
+    <paths>
+        <dir name=".."/>
+    </paths>
+</project>