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