1 //Package for test, maybe there will be full implementation
2 module mutils.linalg.vec;
3 
4 import std.math: sqrt;
5 
6 struct Vec(T, int dim){
7 	static assert(dim>0);
8 	enum dimension=dim;
9 
10 	alias vector this;
11 
12 	union{
13 		T[dim] vector;
14 
15 		static if(dim==2){
16 			struct{
17 				T x;
18 				T y;
19 			}
20 			struct{
21 				T w;
22 				T h;
23 			}
24 		}
25 
26 		static if(dim==3){
27 			struct{
28 				T x;
29 				T y;
30 				T z;
31 			}
32 			struct{
33 				T w;
34 				T h;
35 			}
36 		}
37 	}
38 
39 	this(Args... )(Args values){
40 		static assert(Args.length==dim || Args.length==1);
41 		
42 		static if(Args.length==1){
43 			vector[]=values[0];
44 		}else{
45 			foreach(i, val; values){
46 				vector[i]=values[i];
47 			}
48 		}
49 	}
50 
51 	float length(){
52 		float len=0;
53 		foreach(el; vector){
54 			len+=el*el;
55 		}
56 		return sqrt(len);
57 	}
58 
59 	float length_squared(){
60 		float len=0;
61 		foreach(el; vector){
62 			len+=el*el;
63 		}
64 		return len;
65 	}
66 
67 	void opAssign(T[dim] rhs){
68 		vector=rhs;
69 	}
70 
71 	Vec!(T, dim) opBinary(string op)(Vec!(T, dim) rhs)
72 	{
73 		Vec!(T, dim) ret;
74 		mixin("ret.vector=this.vector[] "~op~" rhs.vector[];");
75 		return ret;
76 	}
77 
78 	Vec!(T, dim) opBinary(string op)(T[dim] rhs)
79 	{
80 		Vec!(T, dim) ret;
81 		mixin("ret.vector=this.vector[] "~op~" rhs[];");
82 		return ret;
83 	}
84 
85 	Vec!(T, dim) opBinary(string op)(float rhs)
86 	{
87 		Vec!(T, dim) ret=this;
88 		foreach(ref v;ret.vector){
89 			mixin("v=cast(T)(v "~op~" rhs);");
90 			
91 		}
92 		return ret;
93 	}
94 
95 	Vec!(T, dim) opBinary(string op)(double rhs)
96 	{
97 		Vec!(T, dim) ret=this;
98 		foreach(ref v;ret.vector){
99 			mixin("v=cast(T)(v "~op~" rhs);");
100 			
101 		}
102 		return ret;
103 	}
104 
105 
106 	import std.format:FormatSpec,formatValue;
107 	/**
108 	 * Preety print
109 	 */
110 	void toString(scope void delegate(const(char)[]) sink, FormatSpec!char fmt)
111 	{
112 		formatValue(sink, vector, fmt);
113 	}
114 
115 	import mutils.serializer.common;
116 	void customSerialize(Load load, Serializer, ContainerOrSlice)(Serializer serializer, ref ContainerOrSlice con){
117 		serializer.serialize!(load)(vector, con);
118 	}
119 
120 
121 }
122 
123 @nogc nothrow pure unittest{
124 	int[2] arr=[1,2];
125 	alias vec2i=Vec!(int, 2);
126 	vec2i v1=vec2i(1, 1);
127 	vec2i v2=vec2i(3);
128 	vec2i v3=arr;
129 	assert(v2==vec2i(3, 3));
130 	v1.opBinary!("+")(v2);
131 	assert((v1+v2)==vec2i(4, 4));
132 	assert((v1*v2)==vec2i(3, 3));
133 	assert((v1/v2)==vec2i(0, 0));
134 	assert((v2/v1)==vec2i(3, 3));
135 }