xref: /aosp_15_r20/external/angle/src/common/vector_utils.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // vector_utils.h: Utility classes implementing various vector operations
7*8975f5c5SAndroid Build Coastguard Worker 
8*8975f5c5SAndroid Build Coastguard Worker #ifndef COMMON_VECTOR_UTILS_H_
9*8975f5c5SAndroid Build Coastguard Worker #define COMMON_VECTOR_UTILS_H_
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include <cmath>
12*8975f5c5SAndroid Build Coastguard Worker #include <cstddef>
13*8975f5c5SAndroid Build Coastguard Worker #include <ostream>
14*8975f5c5SAndroid Build Coastguard Worker #include <type_traits>
15*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
16*8975f5c5SAndroid Build Coastguard Worker 
17*8975f5c5SAndroid Build Coastguard Worker namespace angle
18*8975f5c5SAndroid Build Coastguard Worker {
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
21*8975f5c5SAndroid Build Coastguard Worker class Vector;
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker using Vector2 = Vector<2, float>;
24*8975f5c5SAndroid Build Coastguard Worker using Vector3 = Vector<3, float>;
25*8975f5c5SAndroid Build Coastguard Worker using Vector4 = Vector<4, float>;
26*8975f5c5SAndroid Build Coastguard Worker 
27*8975f5c5SAndroid Build Coastguard Worker using Vector2I = Vector<2, int>;
28*8975f5c5SAndroid Build Coastguard Worker using Vector3I = Vector<3, int>;
29*8975f5c5SAndroid Build Coastguard Worker using Vector4I = Vector<4, int>;
30*8975f5c5SAndroid Build Coastguard Worker 
31*8975f5c5SAndroid Build Coastguard Worker using Vector2U = Vector<2, unsigned int>;
32*8975f5c5SAndroid Build Coastguard Worker using Vector3U = Vector<3, unsigned int>;
33*8975f5c5SAndroid Build Coastguard Worker using Vector4U = Vector<4, unsigned int>;
34*8975f5c5SAndroid Build Coastguard Worker 
35*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
36*8975f5c5SAndroid Build Coastguard Worker class VectorBase
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker   public:
39*8975f5c5SAndroid Build Coastguard Worker     using VectorN = Vector<Dimension, Type>;
40*8975f5c5SAndroid Build Coastguard Worker 
41*8975f5c5SAndroid Build Coastguard Worker     // Constructors
42*8975f5c5SAndroid Build Coastguard Worker     VectorBase() = default;
43*8975f5c5SAndroid Build Coastguard Worker     explicit VectorBase(Type element);
44*8975f5c5SAndroid Build Coastguard Worker 
45*8975f5c5SAndroid Build Coastguard Worker     template <typename Type2>
46*8975f5c5SAndroid Build Coastguard Worker     VectorBase(const VectorBase<Dimension, Type2> &other);
47*8975f5c5SAndroid Build Coastguard Worker 
48*8975f5c5SAndroid Build Coastguard Worker     template <typename Arg1, typename Arg2, typename... Args>
49*8975f5c5SAndroid Build Coastguard Worker     VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &...args);
50*8975f5c5SAndroid Build Coastguard Worker 
51*8975f5c5SAndroid Build Coastguard Worker     // Access the vector backing storage directly
data()52*8975f5c5SAndroid Build Coastguard Worker     const Type *data() const { return mData; }
data()53*8975f5c5SAndroid Build Coastguard Worker     Type *data() { return mData; }
size()54*8975f5c5SAndroid Build Coastguard Worker     constexpr size_t size() const { return Dimension; }
55*8975f5c5SAndroid Build Coastguard Worker 
56*8975f5c5SAndroid Build Coastguard Worker     // Load or store the pointer from / to raw data
57*8975f5c5SAndroid Build Coastguard Worker     static VectorN Load(const Type *source);
58*8975f5c5SAndroid Build Coastguard Worker     static void Store(const VectorN &source, Type *destination);
59*8975f5c5SAndroid Build Coastguard Worker 
60*8975f5c5SAndroid Build Coastguard Worker     // Index the vector
61*8975f5c5SAndroid Build Coastguard Worker     Type &operator[](size_t i) { return mData[i]; }
62*8975f5c5SAndroid Build Coastguard Worker     const Type &operator[](size_t i) const { return mData[i]; }
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker     // Basic arithmetic operations
65*8975f5c5SAndroid Build Coastguard Worker     VectorN operator+() const;
66*8975f5c5SAndroid Build Coastguard Worker     VectorN operator-() const;
67*8975f5c5SAndroid Build Coastguard Worker     VectorN operator+(const VectorN &other) const;
68*8975f5c5SAndroid Build Coastguard Worker     VectorN operator-(const VectorN &other) const;
69*8975f5c5SAndroid Build Coastguard Worker     VectorN operator*(const VectorN &other) const;
70*8975f5c5SAndroid Build Coastguard Worker     VectorN operator/(const VectorN &other) const;
71*8975f5c5SAndroid Build Coastguard Worker     VectorN operator*(Type other) const;
72*8975f5c5SAndroid Build Coastguard Worker     VectorN operator/(Type other) const;
73*8975f5c5SAndroid Build Coastguard Worker     friend VectorN operator*(Type a, const VectorN &b) { return b * a; }
74*8975f5c5SAndroid Build Coastguard Worker 
75*8975f5c5SAndroid Build Coastguard Worker     // Compound arithmetic operations
76*8975f5c5SAndroid Build Coastguard Worker     VectorN &operator+=(const VectorN &other);
77*8975f5c5SAndroid Build Coastguard Worker     VectorN &operator-=(const VectorN &other);
78*8975f5c5SAndroid Build Coastguard Worker     VectorN &operator*=(const VectorN &other);
79*8975f5c5SAndroid Build Coastguard Worker     VectorN &operator/=(const VectorN &other);
80*8975f5c5SAndroid Build Coastguard Worker     VectorN &operator*=(Type other);
81*8975f5c5SAndroid Build Coastguard Worker     VectorN &operator/=(Type other);
82*8975f5c5SAndroid Build Coastguard Worker 
83*8975f5c5SAndroid Build Coastguard Worker     // Comparison operators
84*8975f5c5SAndroid Build Coastguard Worker     bool operator==(const VectorBase<Dimension, Type> &other) const;
85*8975f5c5SAndroid Build Coastguard Worker     bool operator!=(const VectorBase<Dimension, Type> &other) const;
86*8975f5c5SAndroid Build Coastguard Worker 
87*8975f5c5SAndroid Build Coastguard Worker     // Other arithmetic operations
88*8975f5c5SAndroid Build Coastguard Worker     Type length() const;
89*8975f5c5SAndroid Build Coastguard Worker     Type lengthSquared() const;
90*8975f5c5SAndroid Build Coastguard Worker     Type dot(const VectorBase<Dimension, Type> &other) const;
91*8975f5c5SAndroid Build Coastguard Worker     VectorN normalized() const;
92*8975f5c5SAndroid Build Coastguard Worker 
93*8975f5c5SAndroid Build Coastguard Worker   protected:
94*8975f5c5SAndroid Build Coastguard Worker     template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
95*8975f5c5SAndroid Build Coastguard Worker     void initWithList(const Vector<OtherDimension, OtherType> &arg1, const Args &...args);
96*8975f5c5SAndroid Build Coastguard Worker 
97*8975f5c5SAndroid Build Coastguard Worker     // Some old compilers consider this function an alternative for initWithList(Vector)
98*8975f5c5SAndroid Build Coastguard Worker     // when the variant above is more precise. Use SFINAE on the return value to hide
99*8975f5c5SAndroid Build Coastguard Worker     // this variant for non-arithmetic types. The return value is still void.
100*8975f5c5SAndroid Build Coastguard Worker     template <size_t CurrentIndex, typename OtherType, typename... Args>
101*8975f5c5SAndroid Build Coastguard Worker     typename std::enable_if<std::is_arithmetic<OtherType>::value>::type initWithList(
102*8975f5c5SAndroid Build Coastguard Worker         OtherType arg1,
103*8975f5c5SAndroid Build Coastguard Worker         const Args &...args);
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker     template <size_t CurrentIndex>
106*8975f5c5SAndroid Build Coastguard Worker     void initWithList() const;
107*8975f5c5SAndroid Build Coastguard Worker 
108*8975f5c5SAndroid Build Coastguard Worker     template <size_t Dimension2, typename Type2>
109*8975f5c5SAndroid Build Coastguard Worker     friend class VectorBase;
110*8975f5c5SAndroid Build Coastguard Worker 
111*8975f5c5SAndroid Build Coastguard Worker     Type mData[Dimension];
112*8975f5c5SAndroid Build Coastguard Worker };
113*8975f5c5SAndroid Build Coastguard Worker 
114*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
115*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector);
116*8975f5c5SAndroid Build Coastguard Worker 
117*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
118*8975f5c5SAndroid Build Coastguard Worker class Vector<2, Type> : public VectorBase<2, Type>
119*8975f5c5SAndroid Build Coastguard Worker {
120*8975f5c5SAndroid Build Coastguard Worker   public:
121*8975f5c5SAndroid Build Coastguard Worker     // Import the constructors defined in VectorBase
122*8975f5c5SAndroid Build Coastguard Worker     using VectorBase<2, Type>::VectorBase;
123*8975f5c5SAndroid Build Coastguard Worker 
124*8975f5c5SAndroid Build Coastguard Worker     // Element shorthands
x()125*8975f5c5SAndroid Build Coastguard Worker     Type &x() { return this->mData[0]; }
y()126*8975f5c5SAndroid Build Coastguard Worker     Type &y() { return this->mData[1]; }
127*8975f5c5SAndroid Build Coastguard Worker 
x()128*8975f5c5SAndroid Build Coastguard Worker     const Type &x() const { return this->mData[0]; }
y()129*8975f5c5SAndroid Build Coastguard Worker     const Type &y() const { return this->mData[1]; }
130*8975f5c5SAndroid Build Coastguard Worker };
131*8975f5c5SAndroid Build Coastguard Worker 
132*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
133*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector);
134*8975f5c5SAndroid Build Coastguard Worker 
135*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
136*8975f5c5SAndroid Build Coastguard Worker class Vector<3, Type> : public VectorBase<3, Type>
137*8975f5c5SAndroid Build Coastguard Worker {
138*8975f5c5SAndroid Build Coastguard Worker   public:
139*8975f5c5SAndroid Build Coastguard Worker     // Import the constructors defined in VectorBase
140*8975f5c5SAndroid Build Coastguard Worker     using VectorBase<3, Type>::VectorBase;
141*8975f5c5SAndroid Build Coastguard Worker 
142*8975f5c5SAndroid Build Coastguard Worker     // Additional operations
143*8975f5c5SAndroid Build Coastguard Worker     Vector<3, Type> cross(const Vector<3, Type> &other) const;
144*8975f5c5SAndroid Build Coastguard Worker 
145*8975f5c5SAndroid Build Coastguard Worker     // Element shorthands
x()146*8975f5c5SAndroid Build Coastguard Worker     Type &x() { return this->mData[0]; }
y()147*8975f5c5SAndroid Build Coastguard Worker     Type &y() { return this->mData[1]; }
z()148*8975f5c5SAndroid Build Coastguard Worker     Type &z() { return this->mData[2]; }
149*8975f5c5SAndroid Build Coastguard Worker 
x()150*8975f5c5SAndroid Build Coastguard Worker     const Type &x() const { return this->mData[0]; }
y()151*8975f5c5SAndroid Build Coastguard Worker     const Type &y() const { return this->mData[1]; }
z()152*8975f5c5SAndroid Build Coastguard Worker     const Type &z() const { return this->mData[2]; }
153*8975f5c5SAndroid Build Coastguard Worker };
154*8975f5c5SAndroid Build Coastguard Worker 
155*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
156*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector);
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
159*8975f5c5SAndroid Build Coastguard Worker class Vector<4, Type> : public VectorBase<4, Type>
160*8975f5c5SAndroid Build Coastguard Worker {
161*8975f5c5SAndroid Build Coastguard Worker   public:
162*8975f5c5SAndroid Build Coastguard Worker     // Import the constructors defined in VectorBase
163*8975f5c5SAndroid Build Coastguard Worker     using VectorBase<4, Type>::VectorBase;
164*8975f5c5SAndroid Build Coastguard Worker 
165*8975f5c5SAndroid Build Coastguard Worker     // Element shorthands
x()166*8975f5c5SAndroid Build Coastguard Worker     Type &x() { return this->mData[0]; }
y()167*8975f5c5SAndroid Build Coastguard Worker     Type &y() { return this->mData[1]; }
z()168*8975f5c5SAndroid Build Coastguard Worker     Type &z() { return this->mData[2]; }
w()169*8975f5c5SAndroid Build Coastguard Worker     Type &w() { return this->mData[3]; }
170*8975f5c5SAndroid Build Coastguard Worker 
x()171*8975f5c5SAndroid Build Coastguard Worker     const Type &x() const { return this->mData[0]; }
y()172*8975f5c5SAndroid Build Coastguard Worker     const Type &y() const { return this->mData[1]; }
z()173*8975f5c5SAndroid Build Coastguard Worker     const Type &z() const { return this->mData[2]; }
w()174*8975f5c5SAndroid Build Coastguard Worker     const Type &w() const { return this->mData[3]; }
175*8975f5c5SAndroid Build Coastguard Worker };
176*8975f5c5SAndroid Build Coastguard Worker 
177*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
178*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector);
179*8975f5c5SAndroid Build Coastguard Worker 
180*8975f5c5SAndroid Build Coastguard Worker // Implementation of constructors and misc operations
181*8975f5c5SAndroid Build Coastguard Worker 
182*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
VectorBase(Type element)183*8975f5c5SAndroid Build Coastguard Worker VectorBase<Dimension, Type>::VectorBase(Type element)
184*8975f5c5SAndroid Build Coastguard Worker {
185*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
186*8975f5c5SAndroid Build Coastguard Worker     {
187*8975f5c5SAndroid Build Coastguard Worker         mData[i] = element;
188*8975f5c5SAndroid Build Coastguard Worker     }
189*8975f5c5SAndroid Build Coastguard Worker }
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
192*8975f5c5SAndroid Build Coastguard Worker template <typename Type2>
VectorBase(const VectorBase<Dimension,Type2> & other)193*8975f5c5SAndroid Build Coastguard Worker VectorBase<Dimension, Type>::VectorBase(const VectorBase<Dimension, Type2> &other)
194*8975f5c5SAndroid Build Coastguard Worker {
195*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
196*8975f5c5SAndroid Build Coastguard Worker     {
197*8975f5c5SAndroid Build Coastguard Worker         mData[i] = static_cast<Type>(other.mData[i]);
198*8975f5c5SAndroid Build Coastguard Worker     }
199*8975f5c5SAndroid Build Coastguard Worker }
200*8975f5c5SAndroid Build Coastguard Worker 
201*8975f5c5SAndroid Build Coastguard Worker // Ideally we would like to have only two constructors:
202*8975f5c5SAndroid Build Coastguard Worker //  - a scalar constructor that takes Type as a parameter
203*8975f5c5SAndroid Build Coastguard Worker //  - a compound constructor
204*8975f5c5SAndroid Build Coastguard Worker // However if we define the compound constructor for when it has a single arguments, then calling
205*8975f5c5SAndroid Build Coastguard Worker // Vector2(0.0) will be ambiguous. To solve this we take advantage of there being a single compound
206*8975f5c5SAndroid Build Coastguard Worker // constructor with a single argument, which is the copy constructor. We end up with three
207*8975f5c5SAndroid Build Coastguard Worker // constructors:
208*8975f5c5SAndroid Build Coastguard Worker //  - the scalar constructor
209*8975f5c5SAndroid Build Coastguard Worker //  - the copy constructor
210*8975f5c5SAndroid Build Coastguard Worker //  - the compound constructor for two or more arguments, hence the arg1, and arg2 here.
211*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
212*8975f5c5SAndroid Build Coastguard Worker template <typename Arg1, typename Arg2, typename... Args>
VectorBase(const Arg1 & arg1,const Arg2 & arg2,const Args &...args)213*8975f5c5SAndroid Build Coastguard Worker VectorBase<Dimension, Type>::VectorBase(const Arg1 &arg1, const Arg2 &arg2, const Args &...args)
214*8975f5c5SAndroid Build Coastguard Worker {
215*8975f5c5SAndroid Build Coastguard Worker     initWithList<0>(arg1, arg2, args...);
216*8975f5c5SAndroid Build Coastguard Worker }
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
219*8975f5c5SAndroid Build Coastguard Worker template <size_t CurrentIndex, size_t OtherDimension, typename OtherType, typename... Args>
initWithList(const Vector<OtherDimension,OtherType> & arg1,const Args &...args)220*8975f5c5SAndroid Build Coastguard Worker void VectorBase<Dimension, Type>::initWithList(const Vector<OtherDimension, OtherType> &arg1,
221*8975f5c5SAndroid Build Coastguard Worker                                                const Args &...args)
222*8975f5c5SAndroid Build Coastguard Worker {
223*8975f5c5SAndroid Build Coastguard Worker     static_assert(CurrentIndex + OtherDimension <= Dimension,
224*8975f5c5SAndroid Build Coastguard Worker                   "Too much data in the vector constructor.");
225*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < OtherDimension; ++i)
226*8975f5c5SAndroid Build Coastguard Worker     {
227*8975f5c5SAndroid Build Coastguard Worker         mData[CurrentIndex + i] = static_cast<Type>(arg1.mData[i]);
228*8975f5c5SAndroid Build Coastguard Worker     }
229*8975f5c5SAndroid Build Coastguard Worker     initWithList<CurrentIndex + OtherDimension>(args...);
230*8975f5c5SAndroid Build Coastguard Worker }
231*8975f5c5SAndroid Build Coastguard Worker 
232*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
233*8975f5c5SAndroid Build Coastguard Worker template <size_t CurrentIndex, typename OtherType, typename... Args>
234*8975f5c5SAndroid Build Coastguard Worker typename std::enable_if<std::is_arithmetic<OtherType>::value>::type
initWithList(OtherType arg1,const Args &...args)235*8975f5c5SAndroid Build Coastguard Worker VectorBase<Dimension, Type>::initWithList(OtherType arg1, const Args &...args)
236*8975f5c5SAndroid Build Coastguard Worker {
237*8975f5c5SAndroid Build Coastguard Worker     static_assert(CurrentIndex + 1 <= Dimension, "Too much data in the vector constructor.");
238*8975f5c5SAndroid Build Coastguard Worker     mData[CurrentIndex] = static_cast<Type>(arg1);
239*8975f5c5SAndroid Build Coastguard Worker     initWithList<CurrentIndex + 1>(args...);
240*8975f5c5SAndroid Build Coastguard Worker }
241*8975f5c5SAndroid Build Coastguard Worker 
242*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
243*8975f5c5SAndroid Build Coastguard Worker template <size_t CurrentIndex>
initWithList()244*8975f5c5SAndroid Build Coastguard Worker void VectorBase<Dimension, Type>::initWithList() const
245*8975f5c5SAndroid Build Coastguard Worker {
246*8975f5c5SAndroid Build Coastguard Worker     static_assert(CurrentIndex == Dimension, "Not enough data in the vector constructor.");
247*8975f5c5SAndroid Build Coastguard Worker }
248*8975f5c5SAndroid Build Coastguard Worker 
249*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
Load(const Type * source)250*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::Load(const Type *source)
251*8975f5c5SAndroid Build Coastguard Worker {
252*8975f5c5SAndroid Build Coastguard Worker     Vector<Dimension, Type> result;
253*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
254*8975f5c5SAndroid Build Coastguard Worker     {
255*8975f5c5SAndroid Build Coastguard Worker         result.mData[i] = source[i];
256*8975f5c5SAndroid Build Coastguard Worker     }
257*8975f5c5SAndroid Build Coastguard Worker     return result;
258*8975f5c5SAndroid Build Coastguard Worker }
259*8975f5c5SAndroid Build Coastguard Worker 
260*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
Store(const Vector<Dimension,Type> & source,Type * destination)261*8975f5c5SAndroid Build Coastguard Worker void VectorBase<Dimension, Type>::Store(const Vector<Dimension, Type> &source, Type *destination)
262*8975f5c5SAndroid Build Coastguard Worker {
263*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
264*8975f5c5SAndroid Build Coastguard Worker     {
265*8975f5c5SAndroid Build Coastguard Worker         destination[i] = source.mData[i];
266*8975f5c5SAndroid Build Coastguard Worker     }
267*8975f5c5SAndroid Build Coastguard Worker }
268*8975f5c5SAndroid Build Coastguard Worker 
269*8975f5c5SAndroid Build Coastguard Worker // Implementation of basic arithmetic operations
270*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
271*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+() const
272*8975f5c5SAndroid Build Coastguard Worker {
273*8975f5c5SAndroid Build Coastguard Worker     Vector<Dimension, Type> result;
274*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
275*8975f5c5SAndroid Build Coastguard Worker     {
276*8975f5c5SAndroid Build Coastguard Worker         result.mData[i] = +mData[i];
277*8975f5c5SAndroid Build Coastguard Worker     }
278*8975f5c5SAndroid Build Coastguard Worker     return result;
279*8975f5c5SAndroid Build Coastguard Worker }
280*8975f5c5SAndroid Build Coastguard Worker 
281*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
282*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-() const
283*8975f5c5SAndroid Build Coastguard Worker {
284*8975f5c5SAndroid Build Coastguard Worker     Vector<Dimension, Type> result;
285*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
286*8975f5c5SAndroid Build Coastguard Worker     {
287*8975f5c5SAndroid Build Coastguard Worker         result.mData[i] = -mData[i];
288*8975f5c5SAndroid Build Coastguard Worker     }
289*8975f5c5SAndroid Build Coastguard Worker     return result;
290*8975f5c5SAndroid Build Coastguard Worker }
291*8975f5c5SAndroid Build Coastguard Worker 
292*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
293*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator+(
294*8975f5c5SAndroid Build Coastguard Worker     const Vector<Dimension, Type> &other) const
295*8975f5c5SAndroid Build Coastguard Worker {
296*8975f5c5SAndroid Build Coastguard Worker     Vector<Dimension, Type> result;
297*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
298*8975f5c5SAndroid Build Coastguard Worker     {
299*8975f5c5SAndroid Build Coastguard Worker         result.mData[i] = mData[i] + other.mData[i];
300*8975f5c5SAndroid Build Coastguard Worker     }
301*8975f5c5SAndroid Build Coastguard Worker     return result;
302*8975f5c5SAndroid Build Coastguard Worker }
303*8975f5c5SAndroid Build Coastguard Worker 
304*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
305*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator-(
306*8975f5c5SAndroid Build Coastguard Worker     const Vector<Dimension, Type> &other) const
307*8975f5c5SAndroid Build Coastguard Worker {
308*8975f5c5SAndroid Build Coastguard Worker     Vector<Dimension, Type> result;
309*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
310*8975f5c5SAndroid Build Coastguard Worker     {
311*8975f5c5SAndroid Build Coastguard Worker         result.mData[i] = mData[i] - other.mData[i];
312*8975f5c5SAndroid Build Coastguard Worker     }
313*8975f5c5SAndroid Build Coastguard Worker     return result;
314*8975f5c5SAndroid Build Coastguard Worker }
315*8975f5c5SAndroid Build Coastguard Worker 
316*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
317*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(
318*8975f5c5SAndroid Build Coastguard Worker     const Vector<Dimension, Type> &other) const
319*8975f5c5SAndroid Build Coastguard Worker {
320*8975f5c5SAndroid Build Coastguard Worker     Vector<Dimension, Type> result;
321*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
322*8975f5c5SAndroid Build Coastguard Worker     {
323*8975f5c5SAndroid Build Coastguard Worker         result.mData[i] = mData[i] * other.mData[i];
324*8975f5c5SAndroid Build Coastguard Worker     }
325*8975f5c5SAndroid Build Coastguard Worker     return result;
326*8975f5c5SAndroid Build Coastguard Worker }
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
329*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(
330*8975f5c5SAndroid Build Coastguard Worker     const Vector<Dimension, Type> &other) const
331*8975f5c5SAndroid Build Coastguard Worker {
332*8975f5c5SAndroid Build Coastguard Worker     Vector<Dimension, Type> result;
333*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
334*8975f5c5SAndroid Build Coastguard Worker     {
335*8975f5c5SAndroid Build Coastguard Worker         result.mData[i] = mData[i] / other.mData[i];
336*8975f5c5SAndroid Build Coastguard Worker     }
337*8975f5c5SAndroid Build Coastguard Worker     return result;
338*8975f5c5SAndroid Build Coastguard Worker }
339*8975f5c5SAndroid Build Coastguard Worker 
340*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
341*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator*(Type other) const
342*8975f5c5SAndroid Build Coastguard Worker {
343*8975f5c5SAndroid Build Coastguard Worker     Vector<Dimension, Type> result;
344*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
345*8975f5c5SAndroid Build Coastguard Worker     {
346*8975f5c5SAndroid Build Coastguard Worker         result.mData[i] = mData[i] * other;
347*8975f5c5SAndroid Build Coastguard Worker     }
348*8975f5c5SAndroid Build Coastguard Worker     return result;
349*8975f5c5SAndroid Build Coastguard Worker }
350*8975f5c5SAndroid Build Coastguard Worker 
351*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
352*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::operator/(Type other) const
353*8975f5c5SAndroid Build Coastguard Worker {
354*8975f5c5SAndroid Build Coastguard Worker     Vector<Dimension, Type> result;
355*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
356*8975f5c5SAndroid Build Coastguard Worker     {
357*8975f5c5SAndroid Build Coastguard Worker         result.mData[i] = mData[i] / other;
358*8975f5c5SAndroid Build Coastguard Worker     }
359*8975f5c5SAndroid Build Coastguard Worker     return result;
360*8975f5c5SAndroid Build Coastguard Worker }
361*8975f5c5SAndroid Build Coastguard Worker 
362*8975f5c5SAndroid Build Coastguard Worker // Implementation of compound arithmetic operations
363*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
364*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator+=(
365*8975f5c5SAndroid Build Coastguard Worker     const Vector<Dimension, Type> &other)
366*8975f5c5SAndroid Build Coastguard Worker {
367*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
368*8975f5c5SAndroid Build Coastguard Worker     {
369*8975f5c5SAndroid Build Coastguard Worker         mData[i] += other.mData[i];
370*8975f5c5SAndroid Build Coastguard Worker     }
371*8975f5c5SAndroid Build Coastguard Worker     return *static_cast<Vector<Dimension, Type> *>(this);
372*8975f5c5SAndroid Build Coastguard Worker }
373*8975f5c5SAndroid Build Coastguard Worker 
374*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
375*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator-=(
376*8975f5c5SAndroid Build Coastguard Worker     const Vector<Dimension, Type> &other)
377*8975f5c5SAndroid Build Coastguard Worker {
378*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
379*8975f5c5SAndroid Build Coastguard Worker     {
380*8975f5c5SAndroid Build Coastguard Worker         mData[i] -= other.mData[i];
381*8975f5c5SAndroid Build Coastguard Worker     }
382*8975f5c5SAndroid Build Coastguard Worker     return *static_cast<Vector<Dimension, Type> *>(this);
383*8975f5c5SAndroid Build Coastguard Worker }
384*8975f5c5SAndroid Build Coastguard Worker 
385*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
386*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(
387*8975f5c5SAndroid Build Coastguard Worker     const Vector<Dimension, Type> &other)
388*8975f5c5SAndroid Build Coastguard Worker {
389*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
390*8975f5c5SAndroid Build Coastguard Worker     {
391*8975f5c5SAndroid Build Coastguard Worker         mData[i] *= other.mData[i];
392*8975f5c5SAndroid Build Coastguard Worker     }
393*8975f5c5SAndroid Build Coastguard Worker     return *static_cast<Vector<Dimension, Type> *>(this);
394*8975f5c5SAndroid Build Coastguard Worker }
395*8975f5c5SAndroid Build Coastguard Worker 
396*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
397*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(
398*8975f5c5SAndroid Build Coastguard Worker     const Vector<Dimension, Type> &other)
399*8975f5c5SAndroid Build Coastguard Worker {
400*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
401*8975f5c5SAndroid Build Coastguard Worker     {
402*8975f5c5SAndroid Build Coastguard Worker         mData[i] /= other.mData[i];
403*8975f5c5SAndroid Build Coastguard Worker     }
404*8975f5c5SAndroid Build Coastguard Worker     return *static_cast<Vector<Dimension, Type> *>(this);
405*8975f5c5SAndroid Build Coastguard Worker }
406*8975f5c5SAndroid Build Coastguard Worker 
407*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
408*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator*=(Type other)
409*8975f5c5SAndroid Build Coastguard Worker {
410*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
411*8975f5c5SAndroid Build Coastguard Worker     {
412*8975f5c5SAndroid Build Coastguard Worker         mData[i] *= other;
413*8975f5c5SAndroid Build Coastguard Worker     }
414*8975f5c5SAndroid Build Coastguard Worker     return *static_cast<Vector<Dimension, Type> *>(this);
415*8975f5c5SAndroid Build Coastguard Worker }
416*8975f5c5SAndroid Build Coastguard Worker 
417*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
418*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> &VectorBase<Dimension, Type>::operator/=(Type other)
419*8975f5c5SAndroid Build Coastguard Worker {
420*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
421*8975f5c5SAndroid Build Coastguard Worker     {
422*8975f5c5SAndroid Build Coastguard Worker         mData[i] /= other;
423*8975f5c5SAndroid Build Coastguard Worker     }
424*8975f5c5SAndroid Build Coastguard Worker     return *static_cast<Vector<Dimension, Type> *>(this);
425*8975f5c5SAndroid Build Coastguard Worker }
426*8975f5c5SAndroid Build Coastguard Worker 
427*8975f5c5SAndroid Build Coastguard Worker // Implementation of comparison operators
428*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
429*8975f5c5SAndroid Build Coastguard Worker bool VectorBase<Dimension, Type>::operator==(const VectorBase<Dimension, Type> &other) const
430*8975f5c5SAndroid Build Coastguard Worker {
431*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
432*8975f5c5SAndroid Build Coastguard Worker     {
433*8975f5c5SAndroid Build Coastguard Worker         if (mData[i] != other.mData[i])
434*8975f5c5SAndroid Build Coastguard Worker         {
435*8975f5c5SAndroid Build Coastguard Worker             return false;
436*8975f5c5SAndroid Build Coastguard Worker         }
437*8975f5c5SAndroid Build Coastguard Worker     }
438*8975f5c5SAndroid Build Coastguard Worker     return true;
439*8975f5c5SAndroid Build Coastguard Worker }
440*8975f5c5SAndroid Build Coastguard Worker 
441*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
442*8975f5c5SAndroid Build Coastguard Worker bool VectorBase<Dimension, Type>::operator!=(const VectorBase<Dimension, Type> &other) const
443*8975f5c5SAndroid Build Coastguard Worker {
444*8975f5c5SAndroid Build Coastguard Worker     return !(*this == other);
445*8975f5c5SAndroid Build Coastguard Worker }
446*8975f5c5SAndroid Build Coastguard Worker 
447*8975f5c5SAndroid Build Coastguard Worker // Implementation of other arithmetic operations
448*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
length()449*8975f5c5SAndroid Build Coastguard Worker Type VectorBase<Dimension, Type>::length() const
450*8975f5c5SAndroid Build Coastguard Worker {
451*8975f5c5SAndroid Build Coastguard Worker     static_assert(std::is_floating_point<Type>::value,
452*8975f5c5SAndroid Build Coastguard Worker                   "VectorN::length is only defined for floating point vectors");
453*8975f5c5SAndroid Build Coastguard Worker     return std::sqrt(lengthSquared());
454*8975f5c5SAndroid Build Coastguard Worker }
455*8975f5c5SAndroid Build Coastguard Worker 
456*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
lengthSquared()457*8975f5c5SAndroid Build Coastguard Worker Type VectorBase<Dimension, Type>::lengthSquared() const
458*8975f5c5SAndroid Build Coastguard Worker {
459*8975f5c5SAndroid Build Coastguard Worker     return dot(*this);
460*8975f5c5SAndroid Build Coastguard Worker }
461*8975f5c5SAndroid Build Coastguard Worker 
462*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
dot(const VectorBase<Dimension,Type> & other)463*8975f5c5SAndroid Build Coastguard Worker Type VectorBase<Dimension, Type>::dot(const VectorBase<Dimension, Type> &other) const
464*8975f5c5SAndroid Build Coastguard Worker {
465*8975f5c5SAndroid Build Coastguard Worker     Type sum = Type();
466*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < Dimension; ++i)
467*8975f5c5SAndroid Build Coastguard Worker     {
468*8975f5c5SAndroid Build Coastguard Worker         sum += mData[i] * other.mData[i];
469*8975f5c5SAndroid Build Coastguard Worker     }
470*8975f5c5SAndroid Build Coastguard Worker     return sum;
471*8975f5c5SAndroid Build Coastguard Worker }
472*8975f5c5SAndroid Build Coastguard Worker 
473*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
474*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const VectorBase<Dimension, Type> &vector)
475*8975f5c5SAndroid Build Coastguard Worker {
476*8975f5c5SAndroid Build Coastguard Worker     ostream << "[ ";
477*8975f5c5SAndroid Build Coastguard Worker     for (size_t elementIdx = 0; elementIdx < Dimension; elementIdx++)
478*8975f5c5SAndroid Build Coastguard Worker     {
479*8975f5c5SAndroid Build Coastguard Worker         if (elementIdx > 0)
480*8975f5c5SAndroid Build Coastguard Worker         {
481*8975f5c5SAndroid Build Coastguard Worker             ostream << ", ";
482*8975f5c5SAndroid Build Coastguard Worker         }
483*8975f5c5SAndroid Build Coastguard Worker         ostream << vector.data()[elementIdx];
484*8975f5c5SAndroid Build Coastguard Worker     }
485*8975f5c5SAndroid Build Coastguard Worker     ostream << " ]";
486*8975f5c5SAndroid Build Coastguard Worker     return ostream;
487*8975f5c5SAndroid Build Coastguard Worker }
488*8975f5c5SAndroid Build Coastguard Worker 
489*8975f5c5SAndroid Build Coastguard Worker template <size_t Dimension, typename Type>
normalized()490*8975f5c5SAndroid Build Coastguard Worker Vector<Dimension, Type> VectorBase<Dimension, Type>::normalized() const
491*8975f5c5SAndroid Build Coastguard Worker {
492*8975f5c5SAndroid Build Coastguard Worker     static_assert(std::is_floating_point<Type>::value,
493*8975f5c5SAndroid Build Coastguard Worker                   "VectorN::normalized is only defined for floating point vectors");
494*8975f5c5SAndroid Build Coastguard Worker     ASSERT(length() != Type());
495*8975f5c5SAndroid Build Coastguard Worker     return *this / length();
496*8975f5c5SAndroid Build Coastguard Worker }
497*8975f5c5SAndroid Build Coastguard Worker 
498*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
499*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<2, Type> &vector)
500*8975f5c5SAndroid Build Coastguard Worker {
501*8975f5c5SAndroid Build Coastguard Worker     return ostream << static_cast<const VectorBase<2, Type> &>(vector);
502*8975f5c5SAndroid Build Coastguard Worker }
503*8975f5c5SAndroid Build Coastguard Worker 
504*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
cross(const Vector<3,Type> & other)505*8975f5c5SAndroid Build Coastguard Worker Vector<3, Type> Vector<3, Type>::cross(const Vector<3, Type> &other) const
506*8975f5c5SAndroid Build Coastguard Worker {
507*8975f5c5SAndroid Build Coastguard Worker     return Vector<3, Type>(y() * other.z() - z() * other.y(), z() * other.x() - x() * other.z(),
508*8975f5c5SAndroid Build Coastguard Worker                            x() * other.y() - y() * other.x());
509*8975f5c5SAndroid Build Coastguard Worker }
510*8975f5c5SAndroid Build Coastguard Worker 
511*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
512*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<3, Type> &vector)
513*8975f5c5SAndroid Build Coastguard Worker {
514*8975f5c5SAndroid Build Coastguard Worker     return ostream << static_cast<const VectorBase<3, Type> &>(vector);
515*8975f5c5SAndroid Build Coastguard Worker }
516*8975f5c5SAndroid Build Coastguard Worker 
517*8975f5c5SAndroid Build Coastguard Worker template <typename Type>
518*8975f5c5SAndroid Build Coastguard Worker std::ostream &operator<<(std::ostream &ostream, const Vector<4, Type> &vector)
519*8975f5c5SAndroid Build Coastguard Worker {
520*8975f5c5SAndroid Build Coastguard Worker     return ostream << static_cast<const VectorBase<4, Type> &>(vector);
521*8975f5c5SAndroid Build Coastguard Worker }
522*8975f5c5SAndroid Build Coastguard Worker 
523*8975f5c5SAndroid Build Coastguard Worker }  // namespace angle
524*8975f5c5SAndroid Build Coastguard Worker 
525*8975f5c5SAndroid Build Coastguard Worker #endif  // COMMON_VECTOR_UTILS_H_
526