1///////////////////////////////////////////////////////////////////////////////////
2/// OpenGL Mathematics (glm.g-truc.net)
3///
4/// Copyright (c) 2005 - 2014 G-Truc Creation (www.g-truc.net)
5/// Permission is hereby granted, free of charge, to any person obtaining a copy
6/// of this software and associated documentation files (the "Software"), to deal
7/// in the Software without restriction, including without limitation the rights
8/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9/// copies of the Software, and to permit persons to whom the Software is
10/// furnished to do so, subject to the following conditions:
11///
12/// The above copyright notice and this permission notice shall be included in
13/// all copies or substantial portions of the Software.
14///
15/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21/// THE SOFTWARE.
22///
23/// @ref core
24/// @file glm/core/type_tvec4.inl
25/// @date 2008-08-23 / 2011-06-15
26/// @author Christophe Riccio
27///////////////////////////////////////////////////////////////////////////////////
28
29namespace glm{
30namespace detail
31{
32	template <typename T, precision P>
33	GLM_FUNC_QUALIFIER GLM_CONSTEXPR length_t tvec4<T, P>::length() const
34	{
35		return 4;
36	}
37
38	//////////////////////////////////////
39	// Accesses
40
41	template <typename T, precision P>
42	GLM_FUNC_QUALIFIER T & tvec4<T, P>::operator[](length_t i)
43	{
44		assert(i >= 0 && i < this->length());
45		return (&x)[i];
46	}
47
48	template <typename T, precision P>
49	GLM_FUNC_QUALIFIER T const & tvec4<T, P>::operator[](length_t i) const
50	{
51		assert(i >= 0 && i < this->length());
52		return (&x)[i];
53	}
54
55	//////////////////////////////////////
56	// Implicit basic constructors
57
58	template <typename T, precision P>
59	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4() :
60		x(0),
61		y(0),
62		z(0),
63		w(0)
64	{}
65
66	template <typename T, precision P>
67	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4(tvec4<T, P> const & v) :
68		x(v.x),
69		y(v.y),
70		z(v.z),
71		w(v.w)
72	{}
73
74	template <typename T, precision P>
75	template <precision Q>
76	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4(tvec4<T, Q> const & v) :
77		x(v.x),
78		y(v.y),
79		z(v.z),
80		w(v.w)
81	{}
82
83	//////////////////////////////////////
84	// Explicit basic constructors
85
86	template <typename T, precision P>
87	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4(ctor)
88	{}
89
90	template <typename T, precision P>
91	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4(T const & s) :
92		x(s),
93		y(s),
94		z(s),
95		w(s)
96	{}
97
98	template <typename T, precision P>
99	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4
100	(
101		T const & s1,
102		T const & s2,
103		T const & s3,
104		T const & s4
105	) :
106		x(s1),
107		y(s2),
108		z(s3),
109		w(s4)
110	{}
111
112	//////////////////////////////////////
113	// Conversion scalar constructors
114
115	template <typename T, precision P>
116	template <typename A, typename B, typename C, typename D>
117	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4
118	(
119		A const & x,
120		B const & y,
121		C const & z,
122		D const & w
123	) :
124		x(static_cast<T>(x)),
125		y(static_cast<T>(y)),
126		z(static_cast<T>(z)),
127		w(static_cast<T>(w))
128	{}
129
130	template <typename T, precision P>
131	template <typename U, precision Q>
132	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4
133	(
134		tvec4<U, Q> const & v
135	) :
136		x(static_cast<T>(v.x)),
137		y(static_cast<T>(v.y)),
138		z(static_cast<T>(v.z)),
139		w(static_cast<T>(v.w))
140	{}
141
142	//////////////////////////////////////
143	// Conversion vector constructors
144
145	template <typename T, precision P>
146	template <typename A, typename B, typename C, precision Q>
147	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4
148	(
149		tvec2<A, Q> const & v,
150		B const & s1,
151		C const & s2
152	) :
153		x(static_cast<T>(v.x)),
154		y(static_cast<T>(v.y)),
155		z(static_cast<T>(s1)),
156		w(static_cast<T>(s2))
157	{}
158
159	template <typename T, precision P>
160	template <typename A, typename B, typename C, precision Q>
161	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4
162	(
163		A const & s1,
164		tvec2<B, Q> const & v,
165		C const & s2
166	) :
167		x(static_cast<T>(s1)),
168		y(static_cast<T>(v.x)),
169		z(static_cast<T>(v.y)),
170		w(static_cast<T>(s2))
171	{}
172
173	template <typename T, precision P>
174	template <typename A, typename B, typename C, precision Q>
175	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4
176	(
177		A const & s1,
178		B const & s2,
179		tvec2<C, Q> const & v
180	) :
181		x(static_cast<T>(s1)),
182		y(static_cast<T>(s2)),
183		z(static_cast<T>(v.x)),
184		w(static_cast<T>(v.y))
185	{}
186
187	template <typename T, precision P>
188	template <typename A, typename B, precision Q>
189	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4
190	(
191		tvec3<A, Q> const & v,
192		B const & s
193	) :
194		x(static_cast<T>(v.x)),
195		y(static_cast<T>(v.y)),
196		z(static_cast<T>(v.z)),
197		w(static_cast<T>(s))
198	{}
199
200	template <typename T, precision P>
201	template <typename A, typename B, precision Q>
202	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4
203	(
204		A const & s,
205		tvec3<B, Q> const & v
206	) :
207		x(static_cast<T>(s)),
208		y(static_cast<T>(v.x)),
209		z(static_cast<T>(v.y)),
210		w(static_cast<T>(v.z))
211	{}
212
213	template <typename T, precision P>
214	template <typename A, typename B, precision Q>
215	GLM_FUNC_QUALIFIER tvec4<T, P>::tvec4
216	(
217		tvec2<A, Q> const & v1,
218		tvec2<B, Q> const & v2
219	) :
220		x(static_cast<T>(v1.x)),
221		y(static_cast<T>(v1.y)),
222		z(static_cast<T>(v2.x)),
223		w(static_cast<T>(v2.y))
224	{}
225
226	//////////////////////////////////////
227	// Unary arithmetic operators
228
229	template <typename T, precision P>
230	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator= (tvec4<T, P> const & v)
231	{
232		this->x = v.x;
233		this->y = v.y;
234		this->z = v.z;
235		this->w = v.w;
236		return *this;
237	}
238
239	template <typename T, precision P>
240	template <typename U, precision Q>
241	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator= (tvec4<U, Q> const & v)
242	{
243		this->x = static_cast<T>(v.x);
244		this->y = static_cast<T>(v.y);
245		this->z = static_cast<T>(v.z);
246		this->w = static_cast<T>(v.w);
247		return *this;
248	}
249
250	template <typename T, precision P>
251	template <typename U>
252	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator+= (U s)
253	{
254		this->x += static_cast<T>(s);
255		this->y += static_cast<T>(s);
256		this->z += static_cast<T>(s);
257		this->w += static_cast<T>(s);
258		return *this;
259	}
260
261	template <typename T, precision P>
262	template <typename U>
263	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator+= (tvec4<U, P> const & v)
264	{
265		this->x += static_cast<T>(v.x);
266		this->y += static_cast<T>(v.y);
267		this->z += static_cast<T>(v.z);
268		this->w += static_cast<T>(v.w);
269		return *this;
270	}
271
272	template <typename T, precision P>
273	template <typename U>
274	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator-= (U s)
275	{
276		this->x -= static_cast<T>(s);
277		this->y -= static_cast<T>(s);
278		this->z -= static_cast<T>(s);
279		this->w -= static_cast<T>(s);
280		return *this;
281	}
282
283	template <typename T, precision P>
284	template <typename U>
285	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator-= (tvec4<U, P> const & v)
286	{
287		this->x -= static_cast<T>(v.x);
288		this->y -= static_cast<T>(v.y);
289		this->z -= static_cast<T>(v.z);
290		this->w -= static_cast<T>(v.w);
291		return *this;
292	}
293
294	template <typename T, precision P>
295	template <typename U>
296	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator*= (U s)
297	{
298		this->x *= static_cast<T>(s);
299		this->y *= static_cast<T>(s);
300		this->z *= static_cast<T>(s);
301		this->w *= static_cast<T>(s);
302		return *this;
303	}
304
305	template <typename T, precision P>
306	template <typename U>
307	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator*= (tvec4<U, P> const & v)
308	{
309		this->x *= static_cast<T>(v.x);
310		this->y *= static_cast<T>(v.y);
311		this->z *= static_cast<T>(v.z);
312		this->w *= static_cast<T>(v.w);
313		return *this;
314	}
315
316	template <typename T, precision P>
317	template <typename U>
318	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator/= (U s)
319	{
320		this->x /= static_cast<T>(s);
321		this->y /= static_cast<T>(s);
322		this->z /= static_cast<T>(s);
323		this->w /= static_cast<T>(s);
324		return *this;
325	}
326
327	template <typename T, precision P>
328	template <typename U>
329	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator/= (tvec4<U, P> const & v)
330	{
331		this->x /= static_cast<T>(v.x);
332		this->y /= static_cast<T>(v.y);
333		this->z /= static_cast<T>(v.z);
334		this->w /= static_cast<T>(v.w);
335		return *this;
336	}
337
338	//////////////////////////////////////
339	// Increment and decrement operators
340
341	template <typename T, precision P>
342	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator++()
343	{
344		++this->x;
345		++this->y;
346		++this->z;
347		++this->w;
348		return *this;
349	}
350
351	template <typename T, precision P>
352	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator--()
353	{
354		--this->x;
355		--this->y;
356		--this->z;
357		--this->w;
358		return *this;
359	}
360
361	template <typename T, precision P>
362	GLM_FUNC_QUALIFIER tvec4<T, P> tvec4<T, P>::operator++(int)
363	{
364		tvec4<T, P> Result(*this);
365		++*this;
366		return Result;
367	}
368
369	template <typename T, precision P>
370	GLM_FUNC_QUALIFIER tvec4<T, P> tvec4<T, P>::operator--(int)
371	{
372		tvec4<T, P> Result(*this);
373		--*this;
374		return Result;
375	}
376
377	//////////////////////////////////////
378	// Unary bit operators
379
380	template <typename T, precision P>
381	template <typename U>
382	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator%= (U s)
383	{
384		this->x %= static_cast<T>(s);
385		this->y %= static_cast<T>(s);
386		this->z %= static_cast<T>(s);
387		this->w %= static_cast<T>(s);
388		return *this;
389	}
390
391	template <typename T, precision P>
392	template <typename U>
393	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator%= (tvec4<U, P> const & v)
394	{
395		this->x %= static_cast<T>(v.x);
396		this->y %= static_cast<T>(v.y);
397		this->z %= static_cast<T>(v.z);
398		this->w %= static_cast<T>(v.w);
399		return *this;
400	}
401
402	template <typename T, precision P>
403	template <typename U>
404	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator&= (U s)
405	{
406		this->x &= static_cast<T>(s);
407		this->y &= static_cast<T>(s);
408		this->z &= static_cast<T>(s);
409		this->w &= static_cast<T>(s);
410		return *this;
411	}
412
413	template <typename T, precision P>
414	template <typename U>
415	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator&= (tvec4<U, P> const & v)
416	{
417		this->x &= static_cast<T>(v.x);
418		this->y &= static_cast<T>(v.y);
419		this->z &= static_cast<T>(v.z);
420		this->w &= static_cast<T>(v.w);
421		return *this;
422	}
423
424	template <typename T, precision P>
425	template <typename U>
426	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator|= (U s)
427	{
428		this->x |= static_cast<T>(s);
429		this->y |= static_cast<T>(s);
430		this->z |= static_cast<T>(s);
431		this->w |= static_cast<T>(s);
432		return *this;
433	}
434
435	template <typename T, precision P>
436	template <typename U>
437	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator|= (tvec4<U, P> const & v)
438	{
439		this->x |= static_cast<T>(v.x);
440		this->y |= static_cast<T>(v.y);
441		this->z |= static_cast<T>(v.z);
442		this->w |= static_cast<T>(v.w);
443		return *this;
444	}
445
446	template <typename T, precision P>
447	template <typename U>
448	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator^= (U s)
449	{
450		this->x ^= static_cast<T>(s);
451		this->y ^= static_cast<T>(s);
452		this->z ^= static_cast<T>(s);
453		this->w ^= static_cast<T>(s);
454		return *this;
455	}
456
457	template <typename T, precision P>
458	template <typename U>
459	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator^= (tvec4<U, P> const & v)
460	{
461		this->x ^= static_cast<T>(v.x);
462		this->y ^= static_cast<T>(v.y);
463		this->z ^= static_cast<T>(v.z);
464		this->w ^= static_cast<T>(v.w);
465		return *this;
466	}
467
468	template <typename T, precision P>
469	template <typename U>
470	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator<<= (U s)
471	{
472		this->x <<= static_cast<T>(s);
473		this->y <<= static_cast<T>(s);
474		this->z <<= static_cast<T>(s);
475		this->w <<= static_cast<T>(s);
476		return *this;
477	}
478
479	template <typename T, precision P>
480	template <typename U>
481	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator<<= (tvec4<U, P> const & v)
482	{
483		this->x <<= static_cast<T>(v.x);
484		this->y <<= static_cast<T>(v.y);
485		this->z <<= static_cast<T>(v.z);
486		this->w <<= static_cast<T>(v.w);
487		return *this;
488	}
489
490	template <typename T, precision P>
491	template <typename U>
492	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator>>= (U s)
493	{
494		this->x >>= static_cast<T>(s);
495		this->y >>= static_cast<T>(s);
496		this->z >>= static_cast<T>(s);
497		this->w >>= static_cast<T>(s);
498		return *this;
499	}
500
501	template <typename T, precision P>
502	template <typename U>
503	GLM_FUNC_QUALIFIER tvec4<T, P> & tvec4<T, P>::operator>>= (tvec4<U, P> const & v)
504	{
505		this->x >>= static_cast<T>(v.x);
506		this->y >>= static_cast<T>(v.y);
507		this->z >>= static_cast<T>(v.z);
508		this->w >>= static_cast<T>(v.w);
509		return *this;
510	}
511
512	//////////////////////////////////////
513	// Binary arithmetic operators
514
515	template <typename T, precision P>
516	GLM_FUNC_QUALIFIER tvec4<T, P> operator+
517	(
518		tvec4<T, P> const & v,
519		T const & s
520	)
521	{
522		return tvec4<T, P>(
523			v.x + s,
524			v.y + s,
525			v.z + s,
526			v.w + s);
527	}
528
529	template <typename T, precision P>
530	GLM_FUNC_QUALIFIER tvec4<T, P> operator+
531	(
532		T const & s,
533		tvec4<T, P> const & v
534	)
535	{
536		return tvec4<T, P>(
537			s + v.x,
538			s + v.y,
539			s + v.z,
540			s + v.w);
541	}
542
543	template <typename T, precision P>
544	GLM_FUNC_QUALIFIER tvec4<T, P> operator+
545	(
546		tvec4<T, P> const & v1,
547		tvec4<T, P> const & v2
548	)
549	{
550		return tvec4<T, P>(
551			v1.x + v2.x,
552			v1.y + v2.y,
553			v1.z + v2.z,
554			v1.w + v2.w);
555	}
556
557	//operator-
558	template <typename T, precision P>
559	GLM_FUNC_QUALIFIER tvec4<T, P> operator-
560	(
561		tvec4<T, P> const & v,
562		T const & s
563	)
564	{
565		return tvec4<T, P>(
566			v.x - s,
567			v.y - s,
568			v.z - s,
569			v.w - s);
570	}
571
572	template <typename T, precision P>
573	GLM_FUNC_QUALIFIER tvec4<T, P> operator-
574	(
575		T const & s,
576		tvec4<T, P> const & v
577	)
578	{
579		return tvec4<T, P>(
580			s - v.x,
581			s - v.y,
582			s - v.z,
583			s - v.w);
584	}
585
586	template <typename T, precision P>
587	GLM_FUNC_QUALIFIER tvec4<T, P> operator-
588	(
589		tvec4<T, P> const & v1,
590		tvec4<T, P> const & v2
591	)
592	{
593		return tvec4<T, P>(
594			v1.x - v2.x,
595			v1.y - v2.y,
596			v1.z - v2.z,
597			v1.w - v2.w);
598	}
599
600	//operator*
601	template <typename T, precision P>
602	GLM_FUNC_QUALIFIER tvec4<T, P> operator*
603	(
604		tvec4<T, P> const & v,
605		T const & s
606	)
607	{
608		return tvec4<T, P>(
609			v.x * s,
610			v.y * s,
611			v.z * s,
612			v.w * s);
613	}
614
615	template <typename T, precision P>
616	GLM_FUNC_QUALIFIER tvec4<T, P> operator*
617	(
618		T const & s,
619		tvec4<T, P> const & v
620	)
621	{
622		return tvec4<T, P>(
623			s * v.x,
624			s * v.y,
625			s * v.z,
626			s * v.w);
627	}
628
629	template <typename T, precision P>
630	GLM_FUNC_QUALIFIER tvec4<T, P> operator*
631	(
632		tvec4<T, P> const & v1,
633		tvec4<T, P> const & v2
634	)
635	{
636		return tvec4<T, P>(
637			v1.x * v2.x,
638			v1.y * v2.y,
639			v1.z * v2.z,
640			v1.w * v2.w);
641	}
642
643	//operator/
644	template <typename T, precision P>
645	GLM_FUNC_QUALIFIER tvec4<T, P> operator/
646	(
647		tvec4<T, P> const & v,
648		T const & s
649	)
650	{
651		return tvec4<T, P>(
652			v.x / s,
653			v.y / s,
654			v.z / s,
655			v.w / s);
656	}
657
658	template <typename T, precision P>
659	GLM_FUNC_QUALIFIER tvec4<T, P> operator/
660	(
661		T const & s,
662		tvec4<T, P> const & v
663	)
664	{
665		return tvec4<T, P>(
666			s / v.x,
667			s / v.y,
668			s / v.z,
669			s / v.w);
670	}
671
672	template <typename T, precision P>
673	GLM_FUNC_QUALIFIER tvec4<T, P> operator/
674	(
675		tvec4<T, P> const & v1,
676		tvec4<T, P> const & v2
677	)
678	{
679		return tvec4<T, P>(
680			v1.x / v2.x,
681			v1.y / v2.y,
682			v1.z / v2.z,
683			v1.w / v2.w);
684	}
685
686	// Unary constant operators
687	template <typename T, precision P>
688	GLM_FUNC_QUALIFIER tvec4<T, P> operator-
689	(
690		tvec4<T, P> const & v
691	)
692	{
693		return tvec4<T, P>(
694			-v.x,
695			-v.y,
696			-v.z,
697			-v.w);
698	}
699
700	//////////////////////////////////////
701	// Boolean operators
702
703	template <typename T, precision P>
704	GLM_FUNC_QUALIFIER bool operator==
705	(
706		tvec4<T, P> const & v1,
707		tvec4<T, P> const & v2
708	)
709	{
710		return (v1.x == v2.x) && (v1.y == v2.y) && (v1.z == v2.z) && (v1.w == v2.w);
711	}
712
713	template <typename T, precision P>
714	GLM_FUNC_QUALIFIER bool operator!=
715	(
716		tvec4<T, P> const & v1,
717		tvec4<T, P> const & v2
718	)
719	{
720		return (v1.x != v2.x) || (v1.y != v2.y) || (v1.z != v2.z) || (v1.w != v2.w);
721	}
722
723	//////////////////////////////////////
724	// Binary bit operators
725
726	template <typename T, precision P>
727	GLM_FUNC_QUALIFIER tvec4<T, P> operator%
728	(
729		tvec4<T, P> const & v,
730		T const & s
731	)
732	{
733		return tvec4<T, P>(
734			v.x % s,
735			v.y % s,
736			v.z % s,
737			v.w % s);
738	}
739
740	template <typename T, precision P>
741	GLM_FUNC_QUALIFIER tvec4<T, P> operator%
742	(
743		T const & s,
744		tvec4<T, P> const & v
745	)
746	{
747		return tvec4<T, P>(
748			s % v.x,
749			s % v.y,
750			s % v.z,
751			s % v.w);
752	}
753
754	template <typename T, precision P>
755	GLM_FUNC_QUALIFIER tvec4<T, P> operator%
756	(
757		tvec4<T, P> const & v1,
758		tvec4<T, P> const & v2
759	)
760	{
761		return tvec4<T, P>(
762			v1.x % v2.x,
763			v1.y % v2.y,
764			v1.z % v2.z,
765			v1.w % v2.w);
766	}
767
768	template <typename T, precision P>
769	GLM_FUNC_QUALIFIER tvec4<T, P> operator&
770	(
771		tvec4<T, P> const & v,
772		T const & s
773	)
774	{
775		return tvec4<T, P>(
776			v.x & s,
777			v.y & s,
778			v.z & s,
779			v.w & s);
780	}
781
782	template <typename T, precision P>
783	GLM_FUNC_QUALIFIER tvec4<T, P> operator&
784	(
785		T const & s,
786		tvec4<T, P> const & v
787	)
788	{
789		return tvec4<T, P>(
790			s & v.x,
791			s & v.y,
792			s & v.z,
793			s & v.w);
794	}
795
796	template <typename T, precision P>
797	GLM_FUNC_QUALIFIER tvec4<T, P> operator&
798	(
799		tvec4<T, P> const & v1,
800		tvec4<T, P> const & v2
801	)
802	{
803		return tvec4<T, P>(
804			v1.x & v2.x,
805			v1.y & v2.y,
806			v1.z & v2.z,
807			v1.w & v2.w);
808	}
809
810	template <typename T, precision P>
811	GLM_FUNC_QUALIFIER tvec4<T, P> operator|
812	(
813		tvec4<T, P> const & v,
814		T const & s
815	)
816	{
817		return tvec4<T, P>(
818			v.x | s,
819			v.y | s,
820			v.z | s,
821			v.w | s);
822	}
823
824	template <typename T, precision P>
825	GLM_FUNC_QUALIFIER tvec4<T, P> operator|
826	(
827		T const & s,
828		tvec4<T, P> const & v
829	)
830	{
831		return tvec4<T, P>(
832			s | v.x,
833			s | v.y,
834			s | v.z,
835			s | v.w);
836	}
837
838	template <typename T, precision P>
839	GLM_FUNC_QUALIFIER tvec4<T, P> operator|
840	(
841		tvec4<T, P> const & v1,
842		tvec4<T, P> const & v2
843	)
844	{
845		return tvec4<T, P>(
846			v1.x | v2.x,
847			v1.y | v2.y,
848			v1.z | v2.z,
849			v1.w | v2.w);
850	}
851
852	template <typename T, precision P>
853	GLM_FUNC_QUALIFIER tvec4<T, P> operator^
854	(
855		tvec4<T, P> const & v,
856		T const & s
857	)
858	{
859		return tvec4<T, P>(
860			v.x ^ s,
861			v.y ^ s,
862			v.z ^ s,
863			v.w ^ s);
864	}
865
866	template <typename T, precision P>
867	GLM_FUNC_QUALIFIER tvec4<T, P> operator^
868	(
869		T const & s,
870		tvec4<T, P> const & v
871	)
872	{
873		return tvec4<T, P>(
874			s ^ v.x,
875			s ^ v.y,
876			s ^ v.z,
877			s ^ v.w);
878	}
879
880	template <typename T, precision P>
881	GLM_FUNC_QUALIFIER tvec4<T, P> operator^
882	(
883		tvec4<T, P> const & v1,
884		tvec4<T, P> const & v2
885	)
886	{
887		return tvec4<T, P>(
888			v1.x ^ v2.x,
889			v1.y ^ v2.y,
890			v1.z ^ v2.z,
891			v1.w ^ v2.w);
892	}
893
894	template <typename T, precision P>
895	GLM_FUNC_QUALIFIER tvec4<T, P> operator<<
896	(
897		tvec4<T, P> const & v,
898		T const & s
899	)
900	{
901		return tvec4<T, P>(
902			v.x << s,
903			v.y << s,
904			v.z << s,
905			v.w << s);
906	}
907
908	template <typename T, precision P>
909	GLM_FUNC_QUALIFIER tvec4<T, P> operator<<
910	(
911		T const & s,
912		tvec4<T, P> const & v
913	)
914	{
915		return tvec4<T, P>(
916			s << v.x,
917			s << v.y,
918			s << v.z,
919			s << v.w);
920	}
921
922	template <typename T, precision P>
923	GLM_FUNC_QUALIFIER tvec4<T, P> operator<<
924	(
925		tvec4<T, P> const & v1,
926		tvec4<T, P> const & v2
927	)
928	{
929		return tvec4<T, P>(
930			v1.x << v2.x,
931			v1.y << v2.y,
932			v1.z << v2.z,
933			v1.w << v2.w);
934	}
935
936	template <typename T, precision P>
937	GLM_FUNC_QUALIFIER tvec4<T, P> operator>>
938	(
939		tvec4<T, P> const & v,
940		T const & s
941	)
942	{
943		return tvec4<T, P>(
944			v.x >> s,
945			v.y >> s,
946			v.z >> s,
947			v.w >> s);
948	}
949
950	template <typename T, precision P>
951	GLM_FUNC_QUALIFIER tvec4<T, P> operator>>
952	(
953		T const & s,
954		tvec4<T, P> const & v
955	)
956	{
957		return tvec4<T, P>(
958			s >> v.x,
959			s >> v.y,
960			s >> v.z,
961			s >> v.w);
962	}
963
964	template <typename T, precision P>
965	GLM_FUNC_QUALIFIER tvec4<T, P> operator>>
966	(
967		tvec4<T, P> const & v1,
968		tvec4<T, P> const & v2
969	)
970	{
971		return tvec4<T, P>(
972			v1.x >> v2.x,
973			v1.y >> v2.y,
974			v1.z >> v2.z,
975			v1.w >> v2.w);
976	}
977
978	template <typename T, precision P>
979	GLM_FUNC_QUALIFIER tvec4<T, P> operator~
980	(
981		tvec4<T, P> const & v
982	)
983	{
984		return tvec4<T, P>(
985			~v.x,
986			~v.y,
987			~v.z,
988			~v.w);
989	}
990
991}//namespace detail
992}//namespace glm
993