• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
32 namespace tcu
33 {
34 
35 // Accessor proxy class for Vectors.
36 template <typename T, int VecSize, int Size>
37 class VecAccess
38 {
39 public:
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 
48 private:
49 	Vector<T, VecSize>&		m_vector;
50 	int						m_index[Size];
51 };
52 
53 template <typename T, int VecSize, int Size>
VecAccess(Vector<T,VecSize> & v,int x,int y)54 VecAccess<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 
62 template <typename T, int VecSize, int Size>
VecAccess(Vector<T,VecSize> & v,int x,int y,int z)63 VecAccess<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 
72 template <typename T, int VecSize, int Size>
VecAccess(Vector<T,VecSize> & v,int x,int y,int z,int w)73 VecAccess<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 
83 template <typename T, int VecSize, int Size>
operator =(const Vector<T,Size> & v)84 VecAccess<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.
92 template <typename T, int Size>
93 class Vector
94 {
95 public:
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 
getPtr(void) const113 	const T*				getPtr		(void) const { return &m_data[0]; }
getPtr(void)114 	T*						getPtr		(void) { return &m_data[0]; }
115 
116 	// Read-only access.
x(void) const117 	T						x			(void) const { return m_data[0]; }
y(void) const118 	T						y			(void) const { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; }
z(void) const119 	T						z			(void) const { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; }
w(void) const120 	T						w			(void) const { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; }
121 
122 	// Read-write access.
x(void)123 	T&						x			(void) { return m_data[0]; }
y(void)124 	T&						y			(void) { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; }
z(void)125 	T&						z			(void) { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; }
w(void)126 	T&						w			(void) { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; }
127 
128 	// Writable accessors.
xy(void)129 	VecAccess<T, Size, 2>	xy			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 1); }
xz(void)130 	VecAccess<T, Size, 2>	xz			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 2); }
xw(void)131 	VecAccess<T, Size, 2>	xw			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 3); }
yz(void)132 	VecAccess<T, Size, 2>	yz			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 2); }
yw(void)133 	VecAccess<T, Size, 2>	yw			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 3); }
zw(void)134 	VecAccess<T, Size, 2>	zw			(void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 2, 3); }
xyz(void)135 	VecAccess<T, Size, 3>	xyz			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 2); }
xyw(void)136 	VecAccess<T, Size, 3>	xyw			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 3); }
xzw(void)137 	VecAccess<T, Size, 3>	xzw			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 2, 3); }
zyx(void)138 	VecAccess<T, Size, 3>	zyx			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 2, 1, 0); }
yzw(void)139 	VecAccess<T, Size, 3>	yzw			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 1, 2, 3); }
wzy(void)140 	VecAccess<T, Size, 3>	wzy			(void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 3, 2, 1); }
xyzw(void)141 	VecAccess<T, Size, 4>	xyzw		(void) { DE_ASSERT(Size >= 4); return VecAccess<T, Size, 4>(*this, 0, 1, 2, 3); }
142 
143 	// Swizzles.
swizzle(int a) const144 	Vector<T, 1>			swizzle		(int a) const { DE_ASSERT(a >= 0 && a < Size); return Vector<T, 1>(m_data[a]); }
swizzle(int a,int b) const145 	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]); }
swizzle(int a,int b,int c) const146 	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]); }
swizzle(int a,int b,int c,int d) const147 	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 
asFloat(void) const149 	Vector<float, Size>		asFloat		(void) const { return cast<float>();	}
asInt(void) const150 	Vector<int, Size>		asInt		(void) const { return cast<int>();		}
asUint(void) const151 	Vector<deUint32, Size>	asUint		(void) const { return cast<deUint32>();	}
asBool(void) const152 	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 	Vector<T, Size>&		operator=	(const Vector<T, Size>& v);
158 
operator [](int ndx) const159 	const T&				operator[]	(int ndx) const		{ DE_ASSERT(de::inBounds(ndx, 0, Size)); return m_data[ndx]; }
operator [](int ndx)160 	T&						operator[]	(int ndx)			{ DE_ASSERT(de::inBounds(ndx, 0, Size)); return m_data[ndx]; }
161 
operator ==(const Vector<T,Size> & v) const162 	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; }
operator !=(const Vector<T,Size> & v) const163 	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 } DE_WARN_UNUSED_TYPE;
172 
173 template <typename T, int Size>
Vector(void)174 inline Vector<T, Size>::Vector (void)
175 {
176 	for (int i = 0; i < Size; i++)
177 		m_data[i] = T();
178 }
179 
180 template <typename T, int Size>
Vector(T s)181 inline Vector<T, Size>::Vector (T s)
182 {
183 	for (int i = 0; i < Size; i++)
184 		m_data[i] = s;
185 }
186 
187 template <typename T, int Size>
Vector(T x_,T y_)188 inline 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 
195 template <typename T, int Size>
Vector(T x_,T y_,T z_)196 inline 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 
204 template <typename T, int Size>
Vector(T x_,T y_,T z_,T w_)205 inline 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 
214 template <typename T, int Size>
Vector(const Vector<T,Size> & v)215 inline 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 
221 template <typename T, int Size>
operator =(const Vector<T,Size> & v)222 inline Vector<T, Size>& Vector<T, Size>::operator=(const Vector<T, Size>& v)
223 {
224 	for (int i = 0; i < Size; i++)
225 		m_data[i] = v.m_data[i];
226 	return *this;
227 }
228 
229 template <typename T, int Size>
Vector(const T (& v)[Size])230 inline Vector<T, Size>::Vector (const T (&v)[Size])
231 {
232 	for (int i = 0; i < Size; i++)
233 		m_data[i] = v[i];
234 }
235 
236 // VecAccess to Vector cast.
237 template <typename T, int VecSize, int Size>
operator Vector<T,Size>(void) const238 VecAccess<T, VecSize, Size>::operator Vector<T, Size> (void) const
239 {
240 	Vector<T, Size> vec;
241 	for (int i = 0; i < Size; i++)
242 		vec.m_data[i] = m_vector.m_data[m_index[i]];
243 	return vec;
244 }
245 
246 // Type cast.
247 template <typename T, int Size>
248 template <typename NewT>
cast(void) const249 inline Vector<NewT, Size> Vector<T, Size>::cast (void) const
250 {
251 	Vector<NewT, Size> res;
252 	for (int i = 0; i < Size; i++)
253 		res.m_data[i] = NewT(m_data[i]);
254 	return res;
255 }
256 
257 // Size cast.
258 template <typename T, int Size>
259 template <int NewSize>
toWidth(void) const260 inline Vector<T, NewSize> Vector<T, Size>::toWidth (void) const
261 {
262 	Vector<T, NewSize> res;
263 	int i;
264 	for (i = 0; i < deMin32(Size, NewSize); i++)
265 		res.m_data[i] = m_data[i];
266 	for (; i < NewSize; i++)
267 		res.m_data[i] = T(0);
268 	return res;
269 }
270 
271 // Operators.
272 
273 template <typename T, int Size>
operator -(const Vector<T,Size> & a)274 inline Vector<T, Size> operator- (const Vector<T, Size>& a)
275 {
276 	Vector<T, Size> res;
277 	for (int i = 0; i < Size; i++)
278 		res.m_data[i] = -a.m_data[i];
279 	return res;
280 }
281 
282 template <typename T, int Size>
operator +(const Vector<T,Size> & a,const Vector<T,Size> & b)283 inline 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 
291 template <typename T, int Size>
operator -(const Vector<T,Size> & a,const Vector<T,Size> & b)292 inline 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 
300 template <typename T, int Size>
operator *(const Vector<T,Size> & a,const Vector<T,Size> & b)301 inline 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 
309 template <typename T, int Size>
operator /(const Vector<T,Size> & a,const Vector<T,Size> & b)310 inline 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 
318 template <typename T, int Size>
operator <<(const Vector<T,Size> & a,const Vector<T,Size> & b)319 inline 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 
327 template <typename T, int Size>
operator >>(const Vector<T,Size> & a,const Vector<T,Size> & b)328 inline Vector<T, Size> operator>> (const Vector<T, Size>& a, const Vector<T, Size>& b)
329 {
330 	Vector<T, Size> res;
331 	for (int i = 0; i < Size; i++)
332 		res.m_data[i] = a.m_data[i] >> b.m_data[i];
333 	return res;
334 }
335 
336 template <typename T, int Size>
operator *(T s,const Vector<T,Size> & a)337 inline 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 
345 template <typename T, int Size>
operator +(T s,const Vector<T,Size> & a)346 inline 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 
354 template <typename T, int Size>
operator -(T s,const Vector<T,Size> & a)355 inline Vector<T, Size> operator- (T s, const Vector<T, Size>& a)
356 {
357 	Vector<T, Size> res;
358 	for (int i = 0; i < Size; i++)
359 		res.m_data[i] = s - a.m_data[i];
360 	return res;
361 }
362 
363 template <typename T, int Size>
operator -(const Vector<T,Size> & a,T s)364 inline Vector<T, Size> operator- (const Vector<T, Size>& a, T s)
365 {
366 	Vector<T, Size> res;
367 	for (int i = 0; i < Size; i++)
368 		res.m_data[i] = a.m_data[i] - s;
369 	return res;
370 }
371 
372 template <typename T, int Size>
operator /(T s,const Vector<T,Size> & a)373 inline Vector<T, Size> operator/ (T s, const Vector<T, Size>& a)
374 {
375 	Vector<T, Size> res;
376 	for (int i = 0; i < Size; i++)
377 		res.m_data[i] = s / a.m_data[i];
378 	return res;
379 }
380 
381 template <typename T, int Size>
operator *(const Vector<T,Size> & a,T s)382 inline Vector<T, Size> operator* (const Vector<T, Size>& a, T s)	{ return s * a; }
383 
384 template <typename T, int Size>
operator +(const Vector<T,Size> & a,T s)385 inline Vector<T, Size> operator+ (const Vector<T, Size>& a, T s)	{ return s + a; }
386 
387 template <typename T, int Size>
operator /(const Vector<T,Size> & a,T s)388 inline Vector<T, Size> operator/ (const Vector<T, Size>& a, T s)
389 {
390 	Vector<T, Size> res;
391 	for (int i = 0; i < Size; i++)
392 		res.m_data[i] = a.m_data[i] / s;
393 	return res;
394 }
395 
396 template <typename T, int Size>
operator +=(const Vector<T,Size> & v)397 inline Vector<T, Size>& Vector<T, Size>::operator+= (const Vector<T, Size>& v)
398 {
399 	for (int i = 0; i < Size; i++)
400 		m_data[i] += v.m_data[i];
401 	return *this;
402 }
403 
404 template <typename T, int Size>
operator -=(const Vector<T,Size> & v)405 inline Vector<T, Size>& Vector<T, Size>::operator-= (const Vector<T, Size>& v)
406 {
407 	for (int i = 0; i < Size; i++)
408 		m_data[i] -= v.m_data[i];
409 	return *this;
410 }
411 
412 // Stream operator.
413 template <typename T, int Size>
operator <<(std::ostream & stream,const tcu::Vector<T,Size> & vec)414 std::ostream& operator<< (std::ostream& stream, const tcu::Vector<T, Size>& vec)
415 {
416 	stream << "(";
417 	for (int i = 0; i < Size; i++)
418 	{
419 		if (i != 0)
420 			stream << ", ";
421 		stream << vec.m_data[i];
422 	}
423 	stream << ")";
424 	return stream;
425 }
426 
427 } // tcu
428 
429 #endif // _TCUVECTOR_HPP
430