1#ifndef _TCUVECTOR_HPP
2#define _TCUVECTOR_HPP
3/*-------------------------------------------------------------------------
4 * drawElements Quality Program Tester Core
5 * ----------------------------------------
6 *
7 * Copyright 2014 The Android Open Source Project
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Generic vector template.
24 *//*--------------------------------------------------------------------*/
25
26#include "tcuDefs.hpp"
27#include "tcuVectorType.hpp"
28#include "deInt32.h"
29
30#include <ostream>
31
32namespace tcu
33{
34
35// Accessor proxy class for Vectors.
36template <typename T, int VecSize, int Size>
37class VecAccess
38{
39public:
40	explicit				VecAccess	(Vector<T, VecSize>& v, int x, int y);
41	explicit				VecAccess	(Vector<T, VecSize>& v, int x, int y, int z);
42	explicit				VecAccess	(Vector<T, VecSize>& v, int x, int y, int z, int w);
43
44	VecAccess&				operator=	(const Vector<T, Size>& v);
45
46	operator Vector<T, Size> (void) const;
47
48private:
49	Vector<T, VecSize>&		m_vector;
50	int						m_index[Size];
51};
52
53template <typename T, int VecSize, int Size>
54VecAccess<T, VecSize, Size>::VecAccess (Vector<T, VecSize>& v, int x, int y)
55	: m_vector(v)
56{
57	DE_STATIC_ASSERT(Size == 2);
58	m_index[0] = x;
59	m_index[1] = y;
60}
61
62template <typename T, int VecSize, int Size>
63VecAccess<T, VecSize, Size>::VecAccess (Vector<T, VecSize>& v, int x, int y, int z)
64	: m_vector(v)
65{
66	DE_STATIC_ASSERT(Size == 3);
67	m_index[0] = x;
68	m_index[1] = y;
69	m_index[2] = z;
70}
71
72template <typename T, int VecSize, int Size>
73VecAccess<T, VecSize, Size>::VecAccess (Vector<T, VecSize>& v, int x, int y, int z, int w)
74	: m_vector(v)
75{
76	DE_STATIC_ASSERT(Size == 4);
77	m_index[0] = x;
78	m_index[1] = y;
79	m_index[2] = z;
80	m_index[3] = w;
81}
82
83template <typename T, int VecSize, int Size>
84VecAccess<T, VecSize, Size>& VecAccess<T, VecSize, Size>::operator= (const Vector<T, Size>& v)
85{
86	for (int i = 0; i < Size; i++)
87		m_vector.m_data[m_index[i]] = v.m_data[i];
88	return *this;
89}
90
91// Vector class.
92template <typename T, int Size>
93class Vector
94{
95public:
96	typedef	T				Element;
97	enum
98	{
99		SIZE = Size,
100	};
101
102	T	m_data[Size];
103
104	// Constructors.
105	explicit				Vector		(void);
106	explicit				Vector		(T s_); // replicate
107							Vector		(T x_, T y_);
108							Vector		(T x_, T y_, T z_);
109							Vector		(T x_, T y_, T z_, T w_);
110							Vector		(const Vector<T, Size>& v);
111							Vector		(const T (&v)[Size]);
112							~Vector		(void);
113
114	const T*				getPtr		(void) const { return &m_data[0]; }
115	T*						getPtr		(void) { return &m_data[0]; }
116
117	// Read-only access.
118	T						x			(void) const { return m_data[0]; }
119	T						y			(void) const { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; }
120	T						z			(void) const { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; }
121	T						w			(void) const { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; }
122
123	// Read-write access.
124	T&						x			(void) { return m_data[0]; }
125	T&						y			(void) { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; }
126	T&						z			(void) { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; }
127	T&						w			(void) { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; }
128
129	// Writable accessors.
130	VecAccess<T, Size, 2>	xy			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 1); }
131	VecAccess<T, Size, 2>	xz			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 2); }
132	VecAccess<T, Size, 2>	xw			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 3); }
133	VecAccess<T, Size, 2>	yz			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 2); }
134	VecAccess<T, Size, 2>	yw			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 3); }
135	VecAccess<T, Size, 2>	zw			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 2, 3); }
136	VecAccess<T, Size, 3>	xyz			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 2); }
137	VecAccess<T, Size, 3>	xyw			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 3); }
138	VecAccess<T, Size, 3>	xzw			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 2, 3); }
139	VecAccess<T, Size, 3>	zyx			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 2, 1, 0); }
140	VecAccess<T, Size, 3>	yzw			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 1, 2, 3); }
141	VecAccess<T, Size, 3>	wzy			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 3, 2, 1); }
142	VecAccess<T, Size, 4>	xyzw		(void) { DE_ASSERT(Size >= 4); return VecAccess<T, Size, 4>(*this, 0, 1, 2, 3); }
143
144	// Swizzles.
145	const T&				swizzle		(int a) const { DE_ASSERT(a >= 0 && a < Size); return m_data[a]; }
146	Vector<T, 2>			swizzle		(int a, int b) const { DE_ASSERT(a >= 0 && a < Size); DE_ASSERT(b >= 0 && b < Size); return Vector<T, 2>(m_data[a], m_data[b]); }
147	Vector<T, 3>			swizzle		(int a, int b, int c) const { DE_ASSERT(a >= 0 && a < Size); DE_ASSERT(b >= 0 && b < Size); DE_ASSERT(c >= 0 && c < Size); return Vector<T, 3>(m_data[a], m_data[b], m_data[c]); }
148	Vector<T, 4>			swizzle		(int a, int b, int c, int d) const { DE_ASSERT(a >= 0 && a < Size); DE_ASSERT(b >= 0 && b < Size); DE_ASSERT(c >= 0 && c < Size); DE_ASSERT(d >= 0 && d < Size); return Vector<T, 4>(m_data[a], m_data[b], m_data[c], m_data[d]); }
149
150	Vector<float, Size>		asFloat		(void) const { return cast<float>();	}
151	Vector<int, Size>		asInt		(void) const { return cast<int>();		}
152	Vector<deUint32, Size>	asUint		(void) const { return cast<deUint32>();	}
153	Vector<bool, Size>		asBool		(void) const { return cast<bool>();		}
154
155	// Operators.
156	Vector<T, Size>&		operator=	(const Vector<T, Size>& v) { for (int i = 0; i < Size; i++) m_data[i] = v.m_data[i]; return *this; }
157	Vector<T, Size>&		operator+=	(const Vector<T, Size>& v);
158
159	const T&				operator[]	(int ndx) const		{ DE_ASSERT(de::inBounds(ndx, 0, Size)); return m_data[ndx]; }
160	T&						operator[]	(int ndx)			{ DE_ASSERT(de::inBounds(ndx, 0, Size)); return m_data[ndx]; }
161
162	bool					operator==	(const Vector<T, Size>& v) const { for (int i = 0; i < Size; i++) if (m_data[i] != v.m_data[i]) return false; return true; }
163	bool					operator!=	(const Vector<T, Size>& v) const { return !(*this == v); }
164
165	// Miscellaneous conversions.
166	template<typename NewT>
167	Vector<NewT, Size>		cast		(void) const;
168
169	template <int NewSize>
170	Vector<T, NewSize>		toWidth		(void) const;
171};
172
173template <typename T, int Size>
174inline Vector<T, Size>::Vector (void)
175{
176	for (int i = 0; i < Size; i++)
177		m_data[i] = T();
178}
179
180template <typename T, int Size>
181inline Vector<T, Size>::Vector (T s)
182{
183	for (int i = 0; i < Size; i++)
184		m_data[i] = s;
185}
186
187template <typename T, int Size>
188inline Vector<T, Size>::Vector (T x_, T y_)
189{
190	DE_STATIC_ASSERT(Size == 2);
191	m_data[0] = x_;
192	m_data[1] = y_;
193}
194
195template <typename T, int Size>
196inline Vector<T, Size>::Vector (T x_, T y_, T z_)
197{
198	DE_STATIC_ASSERT(Size == 3);
199	m_data[0] = x_;
200	m_data[1] = y_;
201	m_data[2] = z_;
202}
203
204template <typename T, int Size>
205inline Vector<T, Size>::Vector (T x_, T y_, T z_, T w_)
206{
207	DE_STATIC_ASSERT(Size == 4);
208	m_data[0] = x_;
209	m_data[1] = y_;
210	m_data[2] = z_;
211	m_data[3] = w_;
212}
213
214template <typename T, int Size>
215inline Vector<T, Size>::Vector (const Vector<T, Size>& v)
216{
217	for (int i = 0; i < Size; i++)
218		m_data[i] = v.m_data[i];
219}
220
221template <typename T, int Size>
222inline Vector<T, Size>::Vector (const T (&v)[Size])
223{
224	for (int i = 0; i < Size; i++)
225		m_data[i] = v[i];
226}
227
228// VecAccess to Vector cast.
229template <typename T, int VecSize, int Size>
230VecAccess<T, VecSize, Size>::operator Vector<T, Size> (void) const
231{
232	Vector<T, Size> vec;
233	for (int i = 0; i < Size; i++)
234		vec.m_data[i] = m_vector.m_data[m_index[i]];
235	return vec;
236}
237
238// Type cast.
239template <typename T, int Size>
240template <typename NewT>
241inline Vector<NewT, Size> Vector<T, Size>::cast (void) const
242{
243	Vector<NewT, Size> res;
244	for (int i = 0; i < Size; i++)
245		res.m_data[i] = NewT(m_data[i]);
246	return res;
247}
248
249// Size cast.
250template <typename T, int Size>
251template <int NewSize>
252inline Vector<T, NewSize> Vector<T, Size>::toWidth (void) const
253{
254	Vector<T, NewSize> res;
255	int i;
256	for (i = 0; i < deMin32(Size, NewSize); i++)
257		res.m_data[i] = m_data[i];
258	for (; i < NewSize; i++)
259		res.m_data[i] = T(0);
260	return res;
261}
262
263// \todo [petri] Other conversions!
264
265template <typename T, int Size>
266inline Vector<T, Size>::~Vector (void)
267{
268}
269
270// Operators.
271
272template <typename T, int Size>
273inline Vector<T, Size> operator- (const Vector<T, Size>& a)
274{
275	Vector<T, Size> res;
276	for (int i = 0; i < Size; i++)
277		res.m_data[i] = -a.m_data[i];
278	return res;
279}
280
281template <typename T, int Size>
282inline Vector<T, Size> operator+ (const Vector<T, Size>& a, const Vector<T, Size>& b)
283{
284	Vector<T, Size> res;
285	for (int i = 0; i < Size; i++)
286		res.m_data[i] = a.m_data[i] + b.m_data[i];
287	return res;
288}
289
290template <typename T, int Size>
291inline Vector<T, Size> operator- (const Vector<T, Size>& a, const Vector<T, Size>& b)
292{
293	Vector<T, Size> res;
294	for (int i = 0; i < Size; i++)
295		res.m_data[i] = a.m_data[i] - b.m_data[i];
296	return res;
297}
298
299template <typename T, int Size>
300inline Vector<T, Size> operator* (const Vector<T, Size>& a, const Vector<T, Size>& b)
301{
302	Vector<T, Size> res;
303	for (int i = 0; i < Size; i++)
304		res.m_data[i] = a.m_data[i] * b.m_data[i];
305	return res;
306}
307
308template <typename T, int Size>
309inline Vector<T, Size> operator/ (const Vector<T, Size>& a, const Vector<T, Size>& b)
310{
311	Vector<T, Size> res;
312	for (int i = 0; i < Size; i++)
313		res.m_data[i] = a.m_data[i] / b.m_data[i];
314	return res;
315}
316
317template <typename T, int Size>
318inline Vector<T, Size> operator<< (const Vector<T, Size>& a, const Vector<T, Size>& b)
319{
320	Vector<T, Size> res;
321	for (int i = 0; i < Size; i++)
322		res.m_data[i] = a.m_data[i] << b.m_data[i];
323	return res;
324}
325
326template <typename T, int Size>
327inline Vector<T, Size> operator>> (const Vector<T, Size>& a, const Vector<T, Size>& b)
328{
329	Vector<T, Size> res;
330	for (int i = 0; i < Size; i++)
331		res.m_data[i] = a.m_data[i] >> b.m_data[i];
332	return res;
333}
334
335template <typename T, int Size>
336inline Vector<T, Size> operator* (T s, const Vector<T, Size>& a)
337{
338	Vector<T, Size> res;
339	for (int i = 0; i < Size; i++)
340		res.m_data[i] = s * a.m_data[i];
341	return res;
342}
343
344template <typename T, int Size>
345inline Vector<T, Size> operator+ (T s, const Vector<T, Size>& a)
346{
347	Vector<T, Size> res;
348	for (int i = 0; i < Size; i++)
349		res.m_data[i] = s + a.m_data[i];
350	return res;
351}
352
353template <typename T, int Size>
354inline Vector<T, Size> operator- (T s, const Vector<T, Size>& a)
355{
356	Vector<T, Size> res;
357	for (int i = 0; i < Size; i++)
358		res.m_data[i] = s - a.m_data[i];
359	return res;
360}
361
362template <typename T, int Size>
363inline Vector<T, Size> operator- (const Vector<T, Size>& a, T s)
364{
365	Vector<T, Size> res;
366	for (int i = 0; i < Size; i++)
367		res.m_data[i] = a.m_data[i] - s;
368	return res;
369}
370
371template <typename T, int Size>
372inline Vector<T, Size> operator/ (T s, const Vector<T, Size>& a)
373{
374	Vector<T, Size> res;
375	for (int i = 0; i < Size; i++)
376		res.m_data[i] = s / a.m_data[i];
377	return res;
378}
379
380template <typename T, int Size>
381inline Vector<T, Size> operator* (const Vector<T, Size>& a, T s)	{ return s * a; }
382
383template <typename T, int Size>
384inline Vector<T, Size> operator+ (const Vector<T, Size>& a, T s)	{ return s + a; }
385
386template <typename T, int Size>
387inline Vector<T, Size> operator/ (const Vector<T, Size>& a, T s)
388{
389	Vector<T, Size> res;
390	for (int i = 0; i < Size; i++)
391		res.m_data[i] = a.m_data[i] / s;
392	return res;
393}
394
395template <typename T, int Size>
396inline Vector<T, Size>& Vector<T, Size>::operator+= (const Vector<T, Size>& v)
397{
398	for (int i = 0; i < Size; i++)
399		m_data[i] += v.m_data[i];
400	return *this;
401}
402
403// Stream operator.
404template <typename T, int Size>
405std::ostream& operator<< (std::ostream& stream, const tcu::Vector<T, Size>& vec)
406{
407	stream << "(";
408	for (int i = 0; i < Size; i++)
409	{
410		if (i != 0)
411			stream << ", ";
412		stream << vec.m_data[i];
413	}
414	stream << ")";
415	return stream;
416}
417
418} // tcu
419
420#endif // _TCUVECTOR_HPP
421