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
113	const T*				getPtr		(void) const { return &m_data[0]; }
114	T*						getPtr		(void) { return &m_data[0]; }
115
116	// Read-only access.
117	T						x			(void) const { return m_data[0]; }
118	T						y			(void) const { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; }
119	T						z			(void) const { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; }
120	T						w			(void) const { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; }
121
122	// Read-write access.
123	T&						x			(void) { return m_data[0]; }
124	T&						y			(void) { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; }
125	T&						z			(void) { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; }
126	T&						w			(void) { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; }
127
128	// Writable accessors.
129	VecAccess<T, Size, 2>	xy			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 1); }
130	VecAccess<T, Size, 2>	xz			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 2); }
131	VecAccess<T, Size, 2>	xw			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 3); }
132	VecAccess<T, Size, 2>	yz			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 2); }
133	VecAccess<T, Size, 2>	yw			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 3); }
134	VecAccess<T, Size, 2>	zw			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 2, 3); }
135	VecAccess<T, Size, 3>	xyz			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 2); }
136	VecAccess<T, Size, 3>	xyw			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 3); }
137	VecAccess<T, Size, 3>	xzw			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 2, 3); }
138	VecAccess<T, Size, 3>	zyx			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 2, 1, 0); }
139	VecAccess<T, Size, 3>	yzw			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 1, 2, 3); }
140	VecAccess<T, Size, 3>	wzy			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 3, 2, 1); }
141	VecAccess<T, Size, 4>	xyzw		(void) { DE_ASSERT(Size >= 4); return VecAccess<T, Size, 4>(*this, 0, 1, 2, 3); }
142
143	// Swizzles.
144	const T&				swizzle		(int a) const { DE_ASSERT(a >= 0 && a < Size); return m_data[a]; }
145	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]); }
146	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]); }
147	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]); }
148
149	Vector<float, Size>		asFloat		(void) const { return cast<float>();	}
150	Vector<int, Size>		asInt		(void) const { return cast<int>();		}
151	Vector<deUint32, Size>	asUint		(void) const { return cast<deUint32>();	}
152	Vector<bool, Size>		asBool		(void) const { return cast<bool>();		}
153
154	// Operators.
155	Vector<T, Size>&		operator+=	(const Vector<T, Size>& v);
156	Vector<T, Size>&		operator-=	(const Vector<T, Size>& v);
157
158	const T&				operator[]	(int ndx) const		{ DE_ASSERT(de::inBounds(ndx, 0, Size)); return m_data[ndx]; }
159	T&						operator[]	(int ndx)			{ DE_ASSERT(de::inBounds(ndx, 0, Size)); return m_data[ndx]; }
160
161	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; }
162	bool					operator!=	(const Vector<T, Size>& v) const { return !(*this == v); }
163
164	// Miscellaneous conversions.
165	template<typename NewT>
166	Vector<NewT, Size>		cast		(void) const;
167
168	template <int NewSize>
169	Vector<T, NewSize>		toWidth		(void) const;
170} DE_WARN_UNUSED_TYPE;
171
172template <typename T, int Size>
173inline Vector<T, Size>::Vector (void)
174{
175	for (int i = 0; i < Size; i++)
176		m_data[i] = T();
177}
178
179template <typename T, int Size>
180inline Vector<T, Size>::Vector (T s)
181{
182	for (int i = 0; i < Size; i++)
183		m_data[i] = s;
184}
185
186template <typename T, int Size>
187inline Vector<T, Size>::Vector (T x_, T y_)
188{
189	DE_STATIC_ASSERT(Size == 2);
190	m_data[0] = x_;
191	m_data[1] = y_;
192}
193
194template <typename T, int Size>
195inline Vector<T, Size>::Vector (T x_, T y_, T z_)
196{
197	DE_STATIC_ASSERT(Size == 3);
198	m_data[0] = x_;
199	m_data[1] = y_;
200	m_data[2] = z_;
201}
202
203template <typename T, int Size>
204inline Vector<T, Size>::Vector (T x_, T y_, T z_, T w_)
205{
206	DE_STATIC_ASSERT(Size == 4);
207	m_data[0] = x_;
208	m_data[1] = y_;
209	m_data[2] = z_;
210	m_data[3] = w_;
211}
212
213template <typename T, int Size>
214inline Vector<T, Size>::Vector (const Vector<T, Size>& v)
215{
216	for (int i = 0; i < Size; i++)
217		m_data[i] = v.m_data[i];
218}
219
220template <typename T, int Size>
221inline Vector<T, Size>::Vector (const T (&v)[Size])
222{
223	for (int i = 0; i < Size; i++)
224		m_data[i] = v[i];
225}
226
227// VecAccess to Vector cast.
228template <typename T, int VecSize, int Size>
229VecAccess<T, VecSize, Size>::operator Vector<T, Size> (void) const
230{
231	Vector<T, Size> vec;
232	for (int i = 0; i < Size; i++)
233		vec.m_data[i] = m_vector.m_data[m_index[i]];
234	return vec;
235}
236
237// Type cast.
238template <typename T, int Size>
239template <typename NewT>
240inline Vector<NewT, Size> Vector<T, Size>::cast (void) const
241{
242	Vector<NewT, Size> res;
243	for (int i = 0; i < Size; i++)
244		res.m_data[i] = NewT(m_data[i]);
245	return res;
246}
247
248// Size cast.
249template <typename T, int Size>
250template <int NewSize>
251inline Vector<T, NewSize> Vector<T, Size>::toWidth (void) const
252{
253	Vector<T, NewSize> res;
254	int i;
255	for (i = 0; i < deMin32(Size, NewSize); i++)
256		res.m_data[i] = m_data[i];
257	for (; i < NewSize; i++)
258		res.m_data[i] = T(0);
259	return res;
260}
261
262// Operators.
263
264template <typename T, int Size>
265inline Vector<T, Size> operator- (const Vector<T, Size>& a)
266{
267	Vector<T, Size> res;
268	for (int i = 0; i < Size; i++)
269		res.m_data[i] = -a.m_data[i];
270	return res;
271}
272
273template <typename T, int Size>
274inline Vector<T, Size> operator+ (const Vector<T, Size>& a, const Vector<T, Size>& b)
275{
276	Vector<T, Size> res;
277	for (int i = 0; i < Size; i++)
278		res.m_data[i] = a.m_data[i] + b.m_data[i];
279	return res;
280}
281
282template <typename T, int Size>
283inline Vector<T, Size> operator- (const Vector<T, Size>& a, const Vector<T, Size>& b)
284{
285	Vector<T, Size> res;
286	for (int i = 0; i < Size; i++)
287		res.m_data[i] = a.m_data[i] - b.m_data[i];
288	return res;
289}
290
291template <typename T, int Size>
292inline Vector<T, Size> operator* (const Vector<T, Size>& a, const Vector<T, Size>& b)
293{
294	Vector<T, Size> res;
295	for (int i = 0; i < Size; i++)
296		res.m_data[i] = a.m_data[i] * b.m_data[i];
297	return res;
298}
299
300template <typename T, int Size>
301inline Vector<T, Size> operator/ (const Vector<T, Size>& a, const Vector<T, Size>& b)
302{
303	Vector<T, Size> res;
304	for (int i = 0; i < Size; i++)
305		res.m_data[i] = a.m_data[i] / b.m_data[i];
306	return res;
307}
308
309template <typename T, int Size>
310inline Vector<T, Size> operator<< (const Vector<T, Size>& a, const Vector<T, Size>& b)
311{
312	Vector<T, Size> res;
313	for (int i = 0; i < Size; i++)
314		res.m_data[i] = a.m_data[i] << b.m_data[i];
315	return res;
316}
317
318template <typename T, int Size>
319inline Vector<T, Size> operator>> (const Vector<T, Size>& a, const Vector<T, Size>& b)
320{
321	Vector<T, Size> res;
322	for (int i = 0; i < Size; i++)
323		res.m_data[i] = a.m_data[i] >> b.m_data[i];
324	return res;
325}
326
327template <typename T, int Size>
328inline Vector<T, Size> operator* (T s, const Vector<T, Size>& a)
329{
330	Vector<T, Size> res;
331	for (int i = 0; i < Size; i++)
332		res.m_data[i] = s * a.m_data[i];
333	return res;
334}
335
336template <typename T, int Size>
337inline Vector<T, Size> operator+ (T s, const Vector<T, Size>& a)
338{
339	Vector<T, Size> res;
340	for (int i = 0; i < Size; i++)
341		res.m_data[i] = s + a.m_data[i];
342	return res;
343}
344
345template <typename T, int Size>
346inline Vector<T, Size> operator- (T s, const Vector<T, Size>& a)
347{
348	Vector<T, Size> res;
349	for (int i = 0; i < Size; i++)
350		res.m_data[i] = s - a.m_data[i];
351	return res;
352}
353
354template <typename T, int Size>
355inline Vector<T, Size> operator- (const Vector<T, Size>& a, T s)
356{
357	Vector<T, Size> res;
358	for (int i = 0; i < Size; i++)
359		res.m_data[i] = a.m_data[i] - s;
360	return res;
361}
362
363template <typename T, int Size>
364inline Vector<T, Size> operator/ (T s, const Vector<T, Size>& a)
365{
366	Vector<T, Size> res;
367	for (int i = 0; i < Size; i++)
368		res.m_data[i] = s / a.m_data[i];
369	return res;
370}
371
372template <typename T, int Size>
373inline Vector<T, Size> operator* (const Vector<T, Size>& a, T s)	{ return s * a; }
374
375template <typename T, int Size>
376inline Vector<T, Size> operator+ (const Vector<T, Size>& a, T s)	{ return s + a; }
377
378template <typename T, int Size>
379inline Vector<T, Size> operator/ (const Vector<T, Size>& a, T s)
380{
381	Vector<T, Size> res;
382	for (int i = 0; i < Size; i++)
383		res.m_data[i] = a.m_data[i] / s;
384	return res;
385}
386
387template <typename T, int Size>
388inline Vector<T, Size>& Vector<T, Size>::operator+= (const Vector<T, Size>& v)
389{
390	for (int i = 0; i < Size; i++)
391		m_data[i] += v.m_data[i];
392	return *this;
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