| 
					
				 | 
			
			
				@@ -30,15 +30,33 @@ V3* cross(V3* r, const V3* a, const V3* b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return r; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define ADD_OP(i) r->data[i] = a->data[i] + b->data[i] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define SUB_OP(i) r->data[i] = a->data[i] - b->data[i] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define MUL_OP(i) r->data[i] = a->data[i] * b->data[i] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define MUL_F_OP(i) r->data[i] = a->data[i] * f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define DIV_OP(i) r->data[i] = a->data[i] / b->data[i] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define DIV_F_OP(i) r->data[i] = a->data[i] / f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define INVERT_OP(i) r->data[i] = -a->data[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define DOT_OP(i) length += a->data[i] * b->data[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define FLOAT_CAST_OP(i) r->data[i] = (float)a->data[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define INT_CAST_OP(i) r->data[i] = (int)a->data[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define DO2(OP)                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    OP(0);                                                                     \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    OP(1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define DO3(OP)                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DO2(OP);                                                                   \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    OP(2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#define DO4(OP)                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    DO3(OP);                                                                   \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    OP(3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define VECTOR_IMPL(T, N, FT)                                                  \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T* addSet##T(T* r, const T* a) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return add##T(r, r, a);                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T* add##T(T* r, const T* a, const T* b) {                                  \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r->data[i] = a->data[i] + b->data[i];                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(ADD_OP);                                                         \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r;                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -47,9 +65,7 @@ V3* cross(V3* r, const V3* a, const V3* b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T* sub##T(T* r, const T* a, const T* b) {                                  \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r->data[i] = a->data[i] - b->data[i];                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(SUB_OP);                                                         \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r;                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -58,9 +74,7 @@ V3* cross(V3* r, const V3* a, const V3* b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T* mul##T(T* r, const T* a, const T* b) {                                  \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r->data[i] = a->data[i] * b->data[i];                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(MUL_OP);                                                         \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r;                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -69,9 +83,7 @@ V3* cross(V3* r, const V3* a, const V3* b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T* div##T(T* r, const T* a, const T* b) {                                  \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r->data[i] = a->data[i] / b->data[i];                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(DIV_OP);                                                         \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r;                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -80,9 +92,7 @@ V3* cross(V3* r, const V3* a, const V3* b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T* mul##T##F(T* r, const T* a, FT f) {                                     \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r->data[i] = a->data[i] * f;                                       \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(MUL_F_OP);                                                       \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r;                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -91,9 +101,7 @@ V3* cross(V3* r, const V3* a, const V3* b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T* div##T##F(T* r, const T* a, FT f) {                                     \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r->data[i] = a->data[i] / f;                                       \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(DIV_F_OP);                                                       \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r;                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -102,18 +110,14 @@ V3* cross(V3* r, const V3* a, const V3* b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T* invert##T(T* r, const T* a) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r->data[i] = -a->data[i];                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(INVERT_OP);                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r;                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #define VECTOR_IMPL_FLOAT(T, N, CN)                                            \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     float dot##T(const T* a, const T* b) {                                     \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         float length = 0;                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            length += a->data[i] * b->data[i];                                 \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(DOT_OP);                                                         \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return length;                                                         \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -130,16 +134,12 @@ V3* cross(V3* r, const V3* a, const V3* b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     T* convertI##T(T* r, const CN* a) {                                        \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r->data[i] = (float)a->data[i];                                    \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(FLOAT_CAST_OP);                                                  \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r;                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }                                                                          \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                                                                \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     CN* convert##T(CN* r, const T* a) {                                        \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for(int i = 0; i < N; i++) {                                           \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r->data[i] = (int)a->data[i];                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }                                                                      \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        DO##N(INT_CAST_OP);                                                    \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r;                                                              \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |