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 							~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 
    173 template <typename T, int Size>
    174 inline Vector<T, Size>::Vector (void)
    175 {
    176 	for (int i = 0; i < Size; i++)
    177 		m_data[i] = T();
    178 }
    179 
    180 template <typename T, int Size>
    181 inline Vector<T, Size>::Vector (T s)
    182 {
    183 	for (int i = 0; i < Size; i++)
    184 		m_data[i] = s;
    185 }
    186 
    187 template <typename T, int Size>
    188 inline 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 
    195 template <typename T, int Size>
    196 inline 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 
    204 template <typename T, int Size>
    205 inline 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 
    214 template <typename T, int Size>
    215 inline 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 
    221 template <typename T, int Size>
    222 inline 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.
    229 template <typename T, int VecSize, int Size>
    230 VecAccess<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.
    239 template <typename T, int Size>
    240 template <typename NewT>
    241 inline 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.
    250 template <typename T, int Size>
    251 template <int NewSize>
    252 inline 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 
    265 template <typename T, int Size>
    266 inline Vector<T, Size>::~Vector (void)
    267 {
    268 }
    269 
    270 // Operators.
    271 
    272 template <typename T, int Size>
    273 inline 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 
    281 template <typename T, int Size>
    282 inline 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 
    290 template <typename T, int Size>
    291 inline 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 
    299 template <typename T, int Size>
    300 inline 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 
    308 template <typename T, int Size>
    309 inline 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 
    317 template <typename T, int Size>
    318 inline 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 
    326 template <typename T, int Size>
    327 inline 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 
    335 template <typename T, int Size>
    336 inline 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 
    344 template <typename T, int Size>
    345 inline 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 
    353 template <typename T, int Size>
    354 inline 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 
    362 template <typename T, int Size>
    363 inline 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 
    371 template <typename T, int Size>
    372 inline 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 
    380 template <typename T, int Size>
    381 inline Vector<T, Size> operator* (const Vector<T, Size>& a, T s)	{ return s * a; }
    382 
    383 template <typename T, int Size>
    384 inline Vector<T, Size> operator+ (const Vector<T, Size>& a, T s)	{ return s + a; }
    385 
    386 template <typename T, int Size>
    387 inline 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 
    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