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 ~Vector (void);
113
getPtr(void) const114 const T* getPtr (void) const { return &m_data[0]; }
getPtr(void)115 T* getPtr (void) { return &m_data[0]; }
116
117 // Read-only access.
x(void) const118 T x (void) const { return m_data[0]; }
y(void) const119 T y (void) const { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; }
z(void) const120 T z (void) const { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; }
w(void) const121 T w (void) const { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; }
122
123 // Read-write access.
x(void)124 T& x (void) { return m_data[0]; }
y(void)125 T& y (void) { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; }
z(void)126 T& z (void) { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; }
w(void)127 T& w (void) { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; }
128
129 // Writable accessors.
xy(void)130 VecAccess<T, Size, 2> xy (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 1); }
xz(void)131 VecAccess<T, Size, 2> xz (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 2); }
xw(void)132 VecAccess<T, Size, 2> xw (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 3); }
yz(void)133 VecAccess<T, Size, 2> yz (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 2); }
yw(void)134 VecAccess<T, Size, 2> yw (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 3); }
zw(void)135 VecAccess<T, Size, 2> zw (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 2, 3); }
xyz(void)136 VecAccess<T, Size, 3> xyz (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 2); }
xyw(void)137 VecAccess<T, Size, 3> xyw (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 3); }
xzw(void)138 VecAccess<T, Size, 3> xzw (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 2, 3); }
zyx(void)139 VecAccess<T, Size, 3> zyx (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 2, 1, 0); }
yzw(void)140 VecAccess<T, Size, 3> yzw (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 1, 2, 3); }
wzy(void)141 VecAccess<T, Size, 3> wzy (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 3, 2, 1); }
xyzw(void)142 VecAccess<T, Size, 4> xyzw (void) { DE_ASSERT(Size >= 4); return VecAccess<T, Size, 4>(*this, 0, 1, 2, 3); }
143
144 // Swizzles.
swizzle(int a) const145 const T& swizzle (int a) const { DE_ASSERT(a >= 0 && a < Size); return m_data[a]; }
swizzle(int a,int b) const146 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) const147 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) const148 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
asFloat(void) const150 Vector<float, Size> asFloat (void) const { return cast<float>(); }
asInt(void) const151 Vector<int, Size> asInt (void) const { return cast<int>(); }
asUint(void) const152 Vector<deUint32, Size> asUint (void) const { return cast<deUint32>(); }
asBool(void) const153 Vector<bool, Size> asBool (void) const { return cast<bool>(); }
154
155 // Operators.
operator =(const Vector<T,Size> & v)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
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 };
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>
Vector(const T (& v)[Size])222 inline 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.
229 template <typename T, int VecSize, int Size>
operator Vector<T,Size>(void) const230 VecAccess<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.
239 template <typename T, int Size>
240 template <typename NewT>
cast(void) const241 inline 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.
250 template <typename T, int Size>
251 template <int NewSize>
toWidth(void) const252 inline 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
265 template <typename T, int Size>
~Vector(void)266 inline Vector<T, Size>::~Vector (void)
267 {
268 }
269
270 // Operators.
271
272 template <typename T, int Size>
operator -(const Vector<T,Size> & a)273 inline 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
281 template <typename T, int Size>
operator +(const Vector<T,Size> & a,const Vector<T,Size> & b)282 inline 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
290 template <typename T, int Size>
operator -(const Vector<T,Size> & a,const Vector<T,Size> & b)291 inline 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
299 template <typename T, int Size>
operator *(const Vector<T,Size> & a,const Vector<T,Size> & b)300 inline 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
308 template <typename T, int Size>
operator /(const Vector<T,Size> & a,const Vector<T,Size> & b)309 inline 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
317 template <typename T, int Size>
operator <<(const Vector<T,Size> & a,const Vector<T,Size> & b)318 inline 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
326 template <typename T, int Size>
operator >>(const Vector<T,Size> & a,const Vector<T,Size> & b)327 inline 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
335 template <typename T, int Size>
operator *(T s,const Vector<T,Size> & a)336 inline 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
344 template <typename T, int Size>
operator +(T s,const Vector<T,Size> & a)345 inline 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
353 template <typename T, int Size>
operator -(T s,const Vector<T,Size> & a)354 inline 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
362 template <typename T, int Size>
operator -(const Vector<T,Size> & a,T s)363 inline 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
371 template <typename T, int Size>
operator /(T s,const Vector<T,Size> & a)372 inline 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
380 template <typename T, int Size>
operator *(const Vector<T,Size> & a,T s)381 inline Vector<T, Size> operator* (const Vector<T, Size>& a, T s) { return s * a; }
382
383 template <typename T, int Size>
operator +(const Vector<T,Size> & a,T s)384 inline Vector<T, Size> operator+ (const Vector<T, Size>& a, T s) { return s + a; }
385
386 template <typename T, int Size>
operator /(const Vector<T,Size> & a,T s)387 inline 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
395 template <typename T, int Size>
operator +=(const Vector<T,Size> & v)396 inline 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.
404 template <typename T, int Size>
operator <<(std::ostream & stream,const tcu::Vector<T,Size> & vec)405 std::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