Home | History | Annotate | Download | only in common
      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