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> 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> 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> 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> 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 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 Vector<T, 1> swizzle (int a) const { DE_ASSERT(a >= 0 && a < Size); return Vector<T, 1>(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 172 template <typename T, int Size> 173 inline Vector<T, Size>::Vector (void) 174 { 175 for (int i = 0; i < Size; i++) 176 m_data[i] = T(); 177 } 178 179 template <typename T, int Size> 180 inline Vector<T, Size>::Vector (T s) 181 { 182 for (int i = 0; i < Size; i++) 183 m_data[i] = s; 184 } 185 186 template <typename T, int Size> 187 inline 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 194 template <typename T, int Size> 195 inline 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 203 template <typename T, int Size> 204 inline 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 213 template <typename T, int Size> 214 inline 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 220 template <typename T, int Size> 221 inline 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. 228 template <typename T, int VecSize, int Size> 229 VecAccess<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. 238 template <typename T, int Size> 239 template <typename NewT> 240 inline 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. 249 template <typename T, int Size> 250 template <int NewSize> 251 inline 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 264 template <typename T, int Size> 265 inline 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 273 template <typename T, int Size> 274 inline 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 282 template <typename T, int Size> 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> 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> 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> 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> 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> 328 inline 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 336 template <typename T, int Size> 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> 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> 355 inline 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 363 template <typename T, int Size> 364 inline 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 372 template <typename T, int Size> 373 inline Vector<T, Size> operator* (const Vector<T, Size>& a, T s) { return s * a; } 374 375 template <typename T, int Size> 376 inline Vector<T, Size> operator+ (const Vector<T, Size>& a, T s) { return s + a; } 377 378 template <typename T, int Size> 379 inline 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 387 template <typename T, int Size> 388 inline 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 395 template <typename T, int Size> 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> 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