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 ~Vector (void); 113 114 const T* getPtr (void) const { return &m_data[0]; } 115 T* getPtr (void) { return &m_data[0]; } 116 117 // Read-only access. 118 T x (void) const { return m_data[0]; } 119 T y (void) const { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; } 120 T z (void) const { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; } 121 T w (void) const { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; } 122 123 // Read-write access. 124 T& x (void) { return m_data[0]; } 125 T& y (void) { DE_STATIC_ASSERT(Size >= 2); return m_data[1]; } 126 T& z (void) { DE_STATIC_ASSERT(Size >= 3); return m_data[2]; } 127 T& w (void) { DE_STATIC_ASSERT(Size >= 4); return m_data[3]; } 128 129 // Writable accessors. 130 VecAccess<T, Size, 2> xy (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 1); } 131 VecAccess<T, Size, 2> xz (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 2); } 132 VecAccess<T, Size, 2> xw (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 0, 3); } 133 VecAccess<T, Size, 2> yz (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 2); } 134 VecAccess<T, Size, 2> yw (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 1, 3); } 135 VecAccess<T, Size, 2> zw (void) { DE_ASSERT(Size >= 2); return VecAccess<T, Size, 2>(*this, 2, 3); } 136 VecAccess<T, Size, 3> xyz (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 2); } 137 VecAccess<T, Size, 3> xyw (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 1, 3); } 138 VecAccess<T, Size, 3> xzw (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 0, 2, 3); } 139 VecAccess<T, Size, 3> zyx (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 2, 1, 0); } 140 VecAccess<T, Size, 3> yzw (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 1, 2, 3); } 141 VecAccess<T, Size, 3> wzy (void) { DE_ASSERT(Size >= 3); return VecAccess<T, Size, 3>(*this, 3, 2, 1); } 142 VecAccess<T, Size, 4> xyzw (void) { DE_ASSERT(Size >= 4); return VecAccess<T, Size, 4>(*this, 0, 1, 2, 3); } 143 144 // Swizzles. 145 const T& swizzle (int a) const { DE_ASSERT(a >= 0 && a < Size); return m_data[a]; } 146 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]); } 147 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]); } 148 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 150 Vector<float, Size> asFloat (void) const { return cast<float>(); } 151 Vector<int, Size> asInt (void) const { return cast<int>(); } 152 Vector<deUint32, Size> asUint (void) const { return cast<deUint32>(); } 153 Vector<bool, Size> asBool (void) const { return cast<bool>(); } 154 155 // Operators. 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 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; 171}; 172 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> 222inline 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. 229template <typename T, int VecSize, int Size> 230VecAccess<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. 239template <typename T, int Size> 240template <typename NewT> 241inline 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. 250template <typename T, int Size> 251template <int NewSize> 252inline 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 265template <typename T, int Size> 266inline Vector<T, Size>::~Vector (void) 267{ 268} 269 270// Operators. 271 272template <typename T, int Size> 273inline 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 281template <typename T, int Size> 282inline 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 290template <typename T, int Size> 291inline 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 299template <typename T, int Size> 300inline 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 308template <typename T, int Size> 309inline 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 317template <typename T, int Size> 318inline 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 326template <typename T, int Size> 327inline 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 335template <typename T, int Size> 336inline 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 344template <typename T, int Size> 345inline 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 353template <typename T, int Size> 354inline 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 362template <typename T, int Size> 363inline 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 371template <typename T, int Size> 372inline 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 380template <typename T, int Size> 381inline Vector<T, Size> operator* (const Vector<T, Size>& a, T s) { return s * a; } 382 383template <typename T, int Size> 384inline Vector<T, Size> operator+ (const Vector<T, Size>& a, T s) { return s + a; } 385 386template <typename T, int Size> 387inline 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 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