Browse Source

Fixed merge

Christophe Riccio 14 years ago
parent
commit
1eb86ac921

+ 724 - 636
glm/core/_swizzle.hpp

@@ -48,703 +48,791 @@ namespace glm
 	};
 }//namespace glm
 
-
 namespace glm{
 namespace detail
 {
+    //! Internal class for implementing swizzle operators
+    template <typename T, int N>
+    struct _swizzle_base0
+    {
+        typedef T       value_type;
+
+    protected:
+        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.
+        // The size 1 buffer is assumed to aligned to the actual members so that the
+        // elem() 
+        char    _buffer[1];
+    };
+
+    template <typename T, typename V, int E0, int E1, int E2, int E3, int N>
+    struct _swizzle_base1 : public _swizzle_base0<T,N>
+    {
+    };
+
+    template <typename T, typename V, int E0, int E1>
+    struct _swizzle_base1<T,V,E0,E1,-1,-2,2> : public _swizzle_base0<T,2>
+    {
+        V operator ()()  const { return V(this->elem(E0), this->elem(E1)); }
+    };
+
+    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>
+    {
+        V operator ()()  const { return V(this->elem(E0), this->elem(E1), this->elem(E2)); }
+    };
+
+    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 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
+        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 Derived, typename Type, typename Class, int N, int E0, int E1, int E2, int E3, int DUPLICATE_ELEMENTS>
-    struct swizzle_base
+    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>
     {
-        typedef Derived     derived_type;
+        typedef VecType         vec_type;    
 
-        swizzle_base& operator= (const Class& that)
+        _swizzle_base2& operator= (const ValueType& t)
         {
-            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];
-
+                (*this)[i] = t;
             return *this;
         }
 
-        swizzle_base& operator= (const Type& t)
+        _swizzle_base2& operator= (const VecType& that)
         {
-            static const int offset_dst[4] = { E0, E1, E2, E3 };
-
-            for (int i = 0; i < N; ++i)
-                elem(offset_dst[i]) = t;
-
+            struct op { 
+                void operator() (value_type& e, value_type& t) { e = t; } 
+            };
+            _apply_op(that, op());
             return *this;
         }
 
-    protected:
-        Type&         elem   (size_t i)       { return (reinterpret_cast<Type*>(_buffer))[i]; }
-        const Type&   elem   (size_t i) const { return (reinterpret_cast<const Type*>(_buffer))[i]; }
+        void operator -= (const VecType& that)
+        {
+            struct op { 
+                void operator() (value_type& e, value_type& t) { e -= t; } 
+            };
+            _apply_op(that, op());
+        }
 
-        // Use an opaque buffer to *ensure* the compiler doesn't call a constructor.
-        // Otherwise, a vec4 containing all swizzles might end up with 1000s of 
-        // constructor calls
-        char    _buffer[sizeof(Type) * N];
-    };
+        void operator += (const VecType& that)
+        {
+            struct op { 
+                void operator() (value_type& e, value_type& t) { e += t; } 
+            };
+            _apply_op(that, op());
+        }
 
-    template <typename Derived, typename Type, typename Class, int N, int E0, int E1, int E2, int E3>
-    struct swizzle_base<Derived, Type,Class,N,E0,E1,E2,E3,1>
-    {
-        typedef Derived     derived_type;
+        void operator *= (const VecType& that)
+        {
+            struct op { 
+                void operator() (value_type& e, value_type& t) { e *= t; } 
+            };
+            _apply_op(that, op());
+        }
 
-        struct Stub {};
-        swizzle_base& operator= (const Stub& that) {}
-          
-    protected:
-        Type&         elem   (size_t i)       { return (reinterpret_cast<Type*>(_buffer))[i]; }
-        const Type&   elem   (size_t i) const { return (reinterpret_cast<const Type*>(_buffer))[i]; }
+        void operator /= (const VecType& that)
+        {
+            struct op { 
+                void operator() (value_type& e, value_type& t) { e /= t; } 
+            };
+            _apply_op(that, op());
+        }
 
-        char    _buffer[sizeof(Type) * N];      
-    };
+        value_type& operator[]  (size_t i)
+        {
+            static const int offset_dst[4] = { E0, E1, E2, E3 };
+            return elem(offset_dst[i]);
+        }
+        value_type  operator[]  (size_t) const
+        {
+            static const int offset_dst[4] = { E0, E1, E2, E3 };
+            return 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>
-    struct swizzle2 : public swizzle_base<swizzle2<T,P,E0,E1>, T,P,2,E0,E1,0,0,(E0 == E1)>
-    {
-        using swizzle_base<swizzle2<T,P,E0,E1>,T,P,2,E0,E1,0,0,(E0 == E1)>::operator=;
-        P cast() const { return P(this->elem(E0), this->elem(E1)); }
-        operator P () const { return cast(); }
-    };
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1, int E2>
-    struct swizzle2_3 : public swizzle_base<swizzle2_3<T,P,E0,E1,E2>,T,P,2,E0,E1,E2,0,1>
-    {
-        using swizzle_base<swizzle2_3<T,P,E0,E1,E2>,T,P,2,E0,E1,E2,0,1>::operator=;
-        P cast() const { return P(this->elem(E0), this->elem(E1), this->elem(E2)); }
-        operator P () const { return cast(); }
     };
 
-    //! 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<swizzle2_4<T,P,E0,E1,E2,E3>,T,P,2,E0,E1,E2,E3,1>
+    //! 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>
     {
-        using swizzle_base<swizzle2_4<T,P,E0,E1,E2,E3>,T,P,2,E0,E1,E2,E3,1>::operator=;
-        P cast() const { return P(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
-        operator P () const { return cast(); }
-    };
+        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>
-    struct swizzle3 : public swizzle_base<swizzle3<T,P,E0,E1,E2>,T,P,3,E0,E1,E2,0,(E0==E1||E0==E2||E1==E2)>
-    {
-        using swizzle_base<swizzle3<T,P,E0,E1,E2>,T,P,3,E0,E1,E2,0,(E0==E1||E0==E2||E1==E2)>::operator=;
-        P cast() const { return P(this->elem(E0), this->elem(E1), this->elem(E2)); }
-        operator P () const { return cast(); }
-    };
+        struct Stub {};
+        _swizzle_base2& operator= (const Stub& that) {}
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1>
-    struct swizzle3_2 : public swizzle_base<swizzle3_2<T,P,E0,E1>,T,P,2,E0,E1,0,0,(E0==E1)>
-    {
-        using swizzle_base<swizzle3_2<T,P,E0,E1>,T,P,2,E0,E1,0,0,(E0==E1)>::operator=;
-        P cast() const { return P(this->elem(E0), this->elem(E1)); }
-        operator P () const { return cast(); }
+        value_type  operator[]  (size_t) const
+        {
+            static const int offset_dst[4] = { E0, E1, E2, E3 };
+            return elem(offset_dst[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<swizzle3_4<T,P,E0,E1,E2,E3>,T,P,3,E0,E1,E2,E3,1>
+    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)>
     {
-        using swizzle_base<swizzle3_4<T,P,E0,E1,E2,E3>,T,P,3,E0,E1,E2,E3,1>::operator=;
-        P cast() const { return P(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
-        operator P () const { return cast(); }
-    };
+        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, int E3>
-    struct swizzle4 : public swizzle_base<swizzle4<T,P,E0,E1,E2,E3>,T,P,4,E0,E1,E2,E3,(E0==E1||E0==E2||E0==E3||E1==E2||E1==E3||E2==E3)>
-    {
-        using swizzle_base<swizzle4<T,P,E0,E1,E2,E3>,T,P,4,E0,E1,E2,E3,(E0==E1||E0==E2||E0==E3||E1==E2||E1==E3||E2==E3)>::operator=;
-        P cast() const { return P(this->elem(E0), this->elem(E1), this->elem(E2), this->elem(E3)); }
-        operator P () const { return cast(); }
-    };
+        using base_type::operator=;
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1>
-    struct swizzle4_2 : public swizzle_base<swizzle4_2<T,P,E0,E1>,T,P,2,E0,E1,0,0,(E0==E1)>
-    {
-        using swizzle_base<swizzle4_2<T,P,E0,E1>,T,P,2,E0,E1,0,0,(E0==E1)>::operator=;
-        P cast() const { return P(this->elem(E0), this->elem(E1)); }
-        operator P () const { return cast(); }
+        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();                                                       \
+    }
 
-    //! Internal class for implementing swizzle operators
-    template <typename T, typename P, int E0, int E1, int E2>
-    struct swizzle4_3 : public swizzle_base<swizzle4_3<T,P,E0,E1,E2>,T,P,4,E0,E1,E2,0,(E0==E1||E0==E2||E1==E2)>
-    {
-        using swizzle_base<swizzle4_3<T,P,E0,E1,E2>,T,P,4,E0,E1,E2,0,(E0==E1||E0==E2||E1==E2)>::operator=;
-        P cast() const { return P(this->elem(E0), this->elem(E1), this->elem(E2)); }
-        operator P () { return cast(); }
-    };
-
-#define _GLM_SWIZZLE_BINARY_OPERATOR_IMPLEMENTATION(OPERAND)\
-    template <typename T, typename P, int N, typename S0, int E0, int E1, int E2, int E3, int D0, typename S1,int F0, int F1, int F2, int F3, int D1> \
-    typename P operator OPERAND ( \
-        const glm::detail::swizzle_base<S0,T,P,N,E0,E1,E2,E3,D0>& a, \
-        const glm::detail::swizzle_base<S1,T,P,N,F0,F1,F2,F3,D1>& b) \
-    { \
-        return static_cast<const S0&>(a).cast() OPERAND static_cast<const S1&>(b).cast(); \
-    } \
-    \
-    template <typename T, typename P, int N, typename S0, int E0, int E1, int E2, int E3, int D0> \
-    typename P operator OPERAND ( \
-        const glm::detail::swizzle_base<S0,T,P,N,E0,E1,E2,E3,D0>& a, \
-        const typename P& b) \
-    { \
-        return static_cast<const S0&>(a).cast() OPERAND b; \
-    } \
-    \
-    template <typename T, typename P, int N, typename S0, int E0, int E1, int E2, int E3, int D0> \
-    typename P operator OPERAND ( \
-        const typename P& a, \
-        const glm::detail::swizzle_base<S0,T,P,N,E0,E1,E2,E3,D0>& b) \
-    { \
-        return a OPERAND static_cast<const S0&>(b).cast(); \
+//
+// 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();                                                       \
     }
 
-    _GLM_SWIZZLE_BINARY_OPERATOR_IMPLEMENTATION(+)
-    _GLM_SWIZZLE_BINARY_OPERATOR_IMPLEMENTATION(-)
-    _GLM_SWIZZLE_BINARY_OPERATOR_IMPLEMENTATION(*)
-    _GLM_SWIZZLE_BINARY_OPERATOR_IMPLEMENTATION(/)
+//
+// 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,0,3> E0 ## E0 ## E0 ## E3; }; \
-    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,1,3> E0 ## E0 ## E1 ## E3; }; \
-    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,0,2,3> E0 ## E0 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,3,0> E0 ## E0 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,3,1> E0 ## E0 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,3,2> E0 ## E0 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,0,0,3,3> E0 ## E0 ## E3 ## E3; }; \
-    \
-    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,0,3> E0 ## E1 ## E0 ## E3; }; \
-    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,1,3> E0 ## E1 ## E1 ## E3; }; \
-    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,1,2,3> E0 ## E1 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,3,0> E0 ## E1 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,3,1> E0 ## E1 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,3,2> E0 ## E1 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,0,1,3,3> E0 ## E1 ## E3 ## E3; }; \
-    \
-    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,0,3> E0 ## E2 ## E0 ## E3; }; \
-    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,1,3> E0 ## E2 ## E1 ## E3; }; \
-    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,0,2,2,3> E0 ## E2 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,3,0> E0 ## E2 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,3,1> E0 ## E2 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,3,2> E0 ## E2 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,0,2,3,3> E0 ## E2 ## E3 ## E3; }; \
-    \
-    \
-    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,0,3> E1 ## E0 ## E0 ## E3; }; \
-    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,1,3> E1 ## E0 ## E1 ## E3; }; \
-    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,0,2,3> E1 ## E0 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,3,0> E1 ## E0 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,3,1> E1 ## E0 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,3,2> E1 ## E0 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,0,3,3> E1 ## E0 ## E3 ## E3; }; \
-    \
-    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,0,3> E1 ## E1 ## E0 ## E3; }; \
-    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,1,3> E1 ## E1 ## E1 ## E3; }; \
-    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,1,2,3> E1 ## E1 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,3,0> E1 ## E1 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,3,1> E1 ## E1 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,3,2> E1 ## E1 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,1,3,3> E1 ## E1 ## E3 ## E3; }; \
-    \
-    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,0,3> E1 ## E2 ## E0 ## E3; }; \
-    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,1,3> E1 ## E2 ## E1 ## E3; }; \
-    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,1,2,2,3> E1 ## E2 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,3,0> E1 ## E2 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,3,1> E1 ## E2 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,3,2> E1 ## E2 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,2,3,3> E1 ## E2 ## E3 ## E3; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,1,3,0,0> E1 ## E3 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,0,1> E1 ## E3 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,0,2> E1 ## E3 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,0,3> E1 ## E3 ## E0 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,1,0> E1 ## E3 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,1,1> E1 ## E3 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,1,2> E1 ## E3 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,1,3> E1 ## E3 ## E1 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,2,0> E1 ## E3 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,2,1> E1 ## E3 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,2,2> E1 ## E3 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,2,3> E1 ## E3 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,3,0> E1 ## E3 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,3,1> E1 ## E3 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,3,2> E1 ## E3 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,1,3,3,3> E1 ## E3 ## E3 ## E3; }; \
-    \
-    \
-    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,0,3> E2 ## E0 ## E0 ## E3; }; \
-    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,1,3> E2 ## E0 ## E1 ## E3; }; \
-    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,0,2,3> E2 ## E0 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,3,0> E2 ## E0 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,3,1> E2 ## E0 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,3,2> E2 ## E0 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,0,3,3> E2 ## E0 ## E3 ## E3; }; \
-    \
-    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,0,3> E2 ## E1 ## E0 ## E3; }; \
-    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,1,3> E2 ## E1 ## E1 ## E3; }; \
-    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,1,2,3> E2 ## E1 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,3,0> E2 ## E1 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,3,1> E2 ## E1 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,3,2> E2 ## E1 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,1,3,3> E2 ## E1 ## E3 ## E3; }; \
-    \
-    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,0,3> E2 ## E2 ## E0 ## E3; }; \
-    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,1,3> E2 ## E2 ## E1 ## E3; }; \
-    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,2,2,2,3> E2 ## E2 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,3,0> E2 ## E2 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,3,1> E2 ## E2 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,3,2> E2 ## E2 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,2,3,3> E2 ## E2 ## E3 ## E3; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,2,3,0,0> E2 ## E3 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,0,1> E2 ## E3 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,0,2> E2 ## E3 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,0,3> E2 ## E3 ## E0 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,1,0> E2 ## E3 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,1,1> E2 ## E3 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,1,2> E2 ## E3 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,1,3> E2 ## E3 ## E1 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,2,0> E2 ## E3 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,2,1> E2 ## E3 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,2,2> E2 ## E3 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,2,3> E2 ## E3 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,3,0> E2 ## E3 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,3,1> E2 ## E3 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,3,2> E2 ## E3 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,2,3,3,3> E2 ## E3 ## E3 ## E3; }; \
-    \
-    \
-    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,0,3> E3 ## E0 ## E0 ## E3; }; \
-    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,1,3> E3 ## E0 ## E1 ## E3; }; \
-    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,0,2,3> E3 ## E0 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,3,0> E3 ## E0 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,3,1> E3 ## E0 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,3,2> E3 ## E0 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,0,3,3> E3 ## E0 ## E3 ## E3; }; \
-    \
-    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,0,3> E3 ## E1 ## E0 ## E3; }; \
-    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,1,3> E3 ## E1 ## E1 ## E3; }; \
-    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,1,2,3> E3 ## E1 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,3,0> E3 ## E1 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,3,1> E3 ## E1 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,3,2> E3 ## E1 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,1,3,3> E3 ## E1 ## E3 ## E3; }; \
-    \
-    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,0,3> E3 ## E2 ## E0 ## E3; }; \
-    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,1,3> E3 ## E2 ## E1 ## E3; }; \
-    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::swizzle4<T,P,3,2,2,3> E3 ## E2 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,3,0> E3 ## E2 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,3,1> E3 ## E2 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,3,2> E3 ## E2 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,2,3,3> E3 ## E2 ## E3 ## E3; }; \
-    \
-    struct { glm::detail::swizzle4<T,P,3,3,0,0> E3 ## E3 ## E0 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,0,1> E3 ## E3 ## E0 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,0,2> E3 ## E3 ## E0 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,0,3> E3 ## E3 ## E0 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,1,0> E3 ## E3 ## E1 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,1,1> E3 ## E3 ## E1 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,1,2> E3 ## E3 ## E1 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,1,3> E3 ## E3 ## E1 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,2,0> E3 ## E3 ## E2 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,2,1> E3 ## E3 ## E2 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,2,2> E3 ## E3 ## E2 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,2,3> E3 ## E3 ## E2 ## E3; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,3,0> E3 ## E3 ## E3 ## E0; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,3,1> E3 ## E3 ## E3 ## E1; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,3,2> E3 ## E3 ## E3 ## E2; }; \
-    struct { glm::detail::swizzle4<T,P,3,3,3,3> E3 ## E3 ## E3 ## E3; }; 
-
-
-
+    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
 

+ 7 - 1
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)
@@ -116,6 +116,12 @@ namespace detail
 
 		GLM_FUNC_DECL tvec3(tref3<T> const & r);
 
+        template <int E0, int E1, int E2>
+        GLM_FUNC_DECL tvec3(const glm::detail::swizzle<3,T,tvec3<T>,E0,E1,E2,-1>& that)
+        {
+            *this = that();
+        }
+
 		//////////////////////////////////////
 		// Convertion scalar constructors
 

+ 6 - 0
glm/core/type_vec4.hpp

@@ -118,6 +118,12 @@ namespace detail
 
 		GLM_FUNC_DECL tvec4(tref4<T> const & r);
 
+        template <int E0, int E1, int E2, int E3>
+        GLM_FUNC_DECL tvec4(const glm::detail::swizzle<4,T,tvec4<T>,E0,E1,E2,E3>& that)
+        {
+            *this = that();
+        }
+
 		//////////////////////////////////////
 		// Convertion scalar constructors
 

+ 40 - 129
test/core/core_type_vec3.cpp

@@ -196,138 +196,48 @@ int test_vec3_swizzle_operators()
     return Error;
 }
 
-#if 0
-using namespace glm;
-
-//
-// Description : Array and textureless GLSL 2D/3D/4D simplex 
-//               noise functions.
-//      Author : Ian McEwan, Ashima Arts.
-//  Maintainer : ijm
-//     Lastmod : 20110822 (ijm)
-//     License : Copyright (C) 2011 Ashima Arts. All rights reserved.
-//               Distributed under the MIT License. See LICENSE file.
-//               https://github.com/ashima/webgl-noise
-// 
-
-vec4 mod289(vec4 x) {
-  return x - floor(x * (1.0 / 289.0)) * 289.0; }
-
-float mod289(float x) {
-  return x - floor(x * (1.0 / 289.0)) * 289.0; }
-
-vec4 permute(vec4 x) {
-     return mod289(((x*34.0)+1.0)*x);
-}
-
-float permute(float x) {
-     return mod289(((x*34.0)+1.0)*x);
-}
-
-vec4 taylorInvSqrt(vec4 r)
+int test_vec3_swizzle_functions()
 {
-  return 1.79284291400159 - 0.85373472095314 * r;
-}
+    int Error = 0;
 
-float taylorInvSqrt(float r)
-{
-  return 1.79284291400159 - 0.85373472095314 * r;
-}
+    //
+    // 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;
 
-vec4 grad4(float j, vec4 ip)
-  {
-  const vec4 ones = vec4(1.0, 1.0, 1.0, -1.0);
-  vec4 p,s;
-
-  p.xyz = floor( fract (vec3(j) * ip.xyz) * 7.0) * ip.z - 1.0;
-  p.w = 1.5 - dot(abs(p.xyz), ones.xyz);
-  s = vec4(lessThan(p, vec4(0.0)));
-  p.xyz = p.xyz + (s.xyz*2.0 - 1.0) * s.www; 
-
-  return p;
-  }
-
-float snoise(vec4 v)
-  {
-  const vec4  C = vec4( 0.138196601125011,  // (5 - sqrt(5))/20  G4
-                        0.276393202250021,  // 2 * G4
-                        0.414589803375032,  // 3 * G4
-                       -0.447213595499958); // -1 + 4 * G4
-
-// (sqrt(5) - 1)/4 = F4, used once below
-#define F4 0.309016994374947451
-
-// First corner
-  vec4 i  = floor(v + dot(v, vec4(F4)) );
-  vec4 x0 = v -   i + dot(i, C.xxxx);
-
-// Other corners
-
-// Rank sorting originally contributed by Bill Licea-Kane, AMD (formerly ATI)
-  vec4 i0;
-  vec3 isX = step( x0.yzw, x0.xxx );
-  vec3 isYZ = step( x0.zww, x0.yyz );
-//  i0.x = dot( isX, vec3( 1.0 ) );
-  i0.x = isX.x + isX.y + isX.z;
-  i0.yzw = 1.0 - isX;
-//  i0.y += dot( isYZ.xy, vec2( 1.0 ) );
-  i0.y += isYZ.x + isYZ.y;
-  i0.zw += 1.0 - isYZ.xy;
-  i0.z += isYZ.z;
-  i0.w += 1.0 - isYZ.z;
-
-  // i0 now contains the unique values 0,1,2,3 in each channel
-  vec4 i3 = clamp( i0, 0.0, 1.0 );
-  vec4 i2 = clamp( i0-1.0, 0.0, 1.0 );
-  vec4 i1 = clamp( i0-2.0, 0.0, 1.0 );
-
-  //  x0 = x0 - 0.0 + 0.0 * C.xxxx
-  //  x1 = x0 - i1  + 1.0 * C.xxxx
-  //  x2 = x0 - i2  + 2.0 * C.xxxx
-  //  x3 = x0 - i3  + 3.0 * C.xxxx
-  //  x4 = x0 - 1.0 + 4.0 * C.xxxx
-  vec4 x1 = x0 - i1 + C.xxxx;
-  vec4 x2 = x0 - i2 + C.yyyy;
-  vec4 x3 = x0 - i3 + C.zzzz;
-  vec4 x4 = x0 + C.wwww;
-
-// Permutations
-  i = mod289(i); 
-  float j0 = permute( permute( permute( permute(i.w) + i.z) + i.y) + i.x);
-  vec4 j1 = permute( permute( permute( permute (
-             i.w + vec4(i1.w, i2.w, i3.w, 1.0 ))
-           + i.z + vec4(i1.z, i2.z, i3.z, 1.0 ))
-           + i.y + vec4(i1.y, i2.y, i3.y, 1.0 ))
-           + i.x + vec4(i1.x, i2.x, i3.x, 1.0 ));
-
-// Gradients: 7x7x6 points over a cube, mapped onto a 4-cross polytope
-// 7*7*6 = 294, which is close to the ring size 17*17 = 289.
-  vec4 ip = vec4(1.0/294.0, 1.0/49.0, 1.0/7.0, 0.0) ;
-
-  vec4 p0 = grad4(j0,   ip);
-  vec4 p1 = grad4(j1.x, ip);
-  vec4 p2 = grad4(j1.y, ip);
-  vec4 p3 = grad4(j1.z, ip);
-  vec4 p4 = grad4(j1.w, ip);
-
-// Normalise gradients
-  vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3)));
-  p0 *= norm.x;
-  p1 *= norm.y;
-  p2 *= norm.z;
-  p3 *= norm.w;
-  p4 *= taylorInvSqrt(dot(p4,p4));
-
-// Mix contributions from the five corners
-  vec3 m0 = max(0.6 - vec3(dot(x0,x0), dot(x1,x1), dot(x2,x2)), 0.0);
-  vec2 m1 = max(0.6 - vec2(dot(x3,x3), dot(x4,x4)            ), 0.0);
-  m0 = m0 * m0;
-  m1 = m1 * m1;
-  return 49.0 * ( dot(m0*m0, vec3( dot( p0, x0 ), dot( p1, x1 ), dot( p2, x2 )))
-               + dot(m1*m1, vec2( dot( p3, x3 ), dot( p4, x4 ) ) ) ) ;
-
-  }
-#endif
+    return Error;
+}
 
 int main()
 {
@@ -339,6 +249,7 @@ int main()
     Error += test_vec3_swizzle3_3();
     Error += test_vec3_swizzle_half();
     Error += test_vec3_swizzle_operators();
+    Error += test_vec3_swizzle_functions();
 	
 	return Error;
 }