blob: 0a156d5250c80d68a9ea4be39a5d4aa3b948162d [file] [log] [blame]
Jarkko Poyry3c827362014-09-02 11:48:52 +03001#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]);
Jarkko Poyry3c827362014-09-02 11:48:52 +0300112
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.
Jarkko Pöyry65d04b92015-05-22 15:12:50 -0700144 Vector<T, 1> swizzle (int a) const { DE_ASSERT(a >= 0 && a < Size); return Vector<T, 1>(m_data[a]); }
Jarkko Poyry3c827362014-09-02 11:48:52 +0300145 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.
Jarkko Poyry3c827362014-09-02 11:48:52 +0300155 Vector<T, Size>& operator+= (const Vector<T, Size>& v);
Jarkko Pöyry1f99d692014-11-17 14:21:54 -0800156 Vector<T, Size>& operator-= (const Vector<T, Size>& v);
Ricardo Garcia066fea42019-05-06 13:10:12 +0200157 Vector<T, Size>& operator= (const Vector<T, Size>& v);
Jarkko Poyry3c827362014-09-02 11:48:52 +0300158
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;
Jarkko Pöyry93df3752015-02-24 12:37:32 -0800171} DE_WARN_UNUSED_TYPE;
Jarkko Poyry3c827362014-09-02 11:48:52 +0300172
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>
Ricardo Garcia066fea42019-05-06 13:10:12 +0200222inline 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
229template <typename T, int Size>
Jarkko Poyry3c827362014-09-02 11:48:52 +0300230inline 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.
237template <typename T, int VecSize, int Size>
238VecAccess<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.
247template <typename T, int Size>
248template <typename NewT>
249inline 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.
258template <typename T, int Size>
259template <int NewSize>
260inline 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++)
Jarkko Poyry8852c822014-09-11 10:20:23 +0300267 res.m_data[i] = T(0);
Jarkko Poyry3c827362014-09-02 11:48:52 +0300268 return res;
269}
270
Jarkko Poyry3c827362014-09-02 11:48:52 +0300271// Operators.
272
273template <typename T, int Size>
274inline 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
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>> (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
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- (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
363template <typename T, int Size>
364inline 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
372template <typename T, int Size>
373inline 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
381template <typename T, int Size>
382inline Vector<T, Size> operator* (const Vector<T, Size>& a, T s) { return s * a; }
383
384template <typename T, int Size>
385inline Vector<T, Size> operator+ (const Vector<T, Size>& a, T s) { return s + a; }
386
387template <typename T, int Size>
388inline 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
396template <typename T, int Size>
397inline 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
Jarkko Pöyry1f99d692014-11-17 14:21:54 -0800404template <typename T, int Size>
405inline 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
Jarkko Poyry3c827362014-09-02 11:48:52 +0300412// Stream operator.
413template <typename T, int Size>
414std::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