blob: bb7dbfc2b893b937c73228650f48be474826d2ef [file] [log] [blame]
Mathias Agopian595ea772013-08-21 23:10:41 -07001/*
2 * Copyright 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef TVEC_IMPLEMENTATION
18#error "Don't include TVecHelpers.h directly. use ui/vec*.h instead"
19#else
20#undef TVEC_IMPLEMENTATION
21#endif
22
23
24#ifndef UI_TVEC_HELPERS_H
25#define UI_TVEC_HELPERS_H
26
27#include <stdint.h>
28#include <sys/types.h>
29
30#define PURE __attribute__((pure))
31
32namespace android {
33// -------------------------------------------------------------------------------------
34
35/*
36 * No user serviceable parts here.
37 *
38 * Don't use this file directly, instead include ui/vec{2|3|4}.h
39 */
40
41/*
42 * This class casts itself into anything and assign itself from anything!
43 * Use with caution!
44 */
45template <typename TYPE>
46struct Impersonator {
47 Impersonator& operator = (const TYPE& rhs) {
48 reinterpret_cast<TYPE&>(*this) = rhs;
49 return *this;
50 }
51 operator TYPE& () {
52 return reinterpret_cast<TYPE&>(*this);
53 }
54 operator TYPE const& () const {
55 return reinterpret_cast<TYPE const&>(*this);
56 }
57};
58
59/*
Mathias Agopian1d4d8f92013-09-01 21:35:36 -070060 * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
Mathias Agopian595ea772013-08-21 23:10:41 -070061 * operators on a vector of type BASE<T>.
62 *
63 * BASE only needs to implement operator[] and size().
Mathias Agopian1d4d8f92013-09-01 21:35:36 -070064 * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
Mathias Agopian595ea772013-08-21 23:10:41 -070065 * get all the functionality here.
66 */
67
68template <template<typename T> class BASE, typename T>
Mathias Agopian1d4d8f92013-09-01 21:35:36 -070069class TVecAddOperators {
Mathias Agopian595ea772013-08-21 23:10:41 -070070public:
71 /* compound assignment from a another vector of the same size but different
72 * element type.
73 */
74 template <typename OTHER>
75 BASE<T>& operator += (const BASE<OTHER>& v) {
76 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
77 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
78 rhs[i] += v[i];
79 }
80 return rhs;
81 }
82 template <typename OTHER>
83 BASE<T>& operator -= (const BASE<OTHER>& v) {
84 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
85 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
86 rhs[i] -= v[i];
87 }
88 return rhs;
89 }
Mathias Agopian595ea772013-08-21 23:10:41 -070090
91 /* compound assignment from a another vector of the same type.
92 * These operators can be used for implicit conversion and handle operations
93 * like "vector *= scalar" by letting the compiler implicitly convert a scalar
94 * to a vector (assuming the BASE<T> allows it).
95 */
96 BASE<T>& operator += (const BASE<T>& v) {
97 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
98 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
99 rhs[i] += v[i];
100 }
101 return rhs;
102 }
103 BASE<T>& operator -= (const BASE<T>& v) {
104 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
105 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
106 rhs[i] -= v[i];
107 }
108 return rhs;
109 }
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700110
111 /*
112 * NOTE: the functions below ARE NOT member methods. They are friend functions
113 * with they definition inlined with their declaration. This makes these
114 * template functions available to the compiler when (and only when) this class
115 * is instantiated, at which point they're only templated on the 2nd parameter
116 * (the first one, BASE<T> being known).
117 */
118
119 /* The operators below handle operation between vectors of the same side
120 * but of a different element type.
121 */
122 template<typename RT>
123 friend inline
124 BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) {
125 return BASE<T>(lv) += rv;
126 }
127 template<typename RT>
128 friend inline
129 BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) {
130 return BASE<T>(lv) -= rv;
131 }
132
133 /* The operators below (which are not templates once this class is instanced,
134 * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
135 * These handle operations like "vector * scalar" and "scalar * vector" by
136 * letting the compiler implicitly convert a scalar to a vector (assuming
137 * the BASE<T> allows it).
138 */
139 friend inline
140 BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) {
141 return BASE<T>(lv) += rv;
142 }
143 friend inline
144 BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) {
145 return BASE<T>(lv) -= rv;
146 }
147};
148
149template <template<typename T> class BASE, typename T>
150class TVecProductOperators {
151public:
152 /* compound assignment from a another vector of the same size but different
153 * element type.
154 */
155 template <typename OTHER>
156 BASE<T>& operator *= (const BASE<OTHER>& v) {
157 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
158 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
159 rhs[i] *= v[i];
160 }
161 return rhs;
162 }
163 template <typename OTHER>
164 BASE<T>& operator /= (const BASE<OTHER>& v) {
165 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
166 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
167 rhs[i] /= v[i];
168 }
169 return rhs;
170 }
171
172 /* compound assignment from a another vector of the same type.
173 * These operators can be used for implicit conversion and handle operations
174 * like "vector *= scalar" by letting the compiler implicitly convert a scalar
175 * to a vector (assuming the BASE<T> allows it).
176 */
Mathias Agopian595ea772013-08-21 23:10:41 -0700177 BASE<T>& operator *= (const BASE<T>& v) {
178 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
179 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
180 rhs[i] *= v[i];
181 }
182 return rhs;
183 }
184 BASE<T>& operator /= (const BASE<T>& v) {
185 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
186 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
187 rhs[i] /= v[i];
188 }
189 return rhs;
190 }
191
192 /*
193 * NOTE: the functions below ARE NOT member methods. They are friend functions
194 * with they definition inlined with their declaration. This makes these
195 * template functions available to the compiler when (and only when) this class
196 * is instantiated, at which point they're only templated on the 2nd parameter
197 * (the first one, BASE<T> being known).
198 */
199
200 /* The operators below handle operation between vectors of the same side
201 * but of a different element type.
202 */
203 template<typename RT>
204 friend inline
Mathias Agopian595ea772013-08-21 23:10:41 -0700205 BASE<T> PURE operator *(const BASE<T>& lv, const BASE<RT>& rv) {
206 return BASE<T>(lv) *= rv;
207 }
208 template<typename RT>
209 friend inline
210 BASE<T> PURE operator /(const BASE<T>& lv, const BASE<RT>& rv) {
211 return BASE<T>(lv) /= rv;
212 }
213
214 /* The operators below (which are not templates once this class is instanced,
215 * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
216 * These handle operations like "vector * scalar" and "scalar * vector" by
217 * letting the compiler implicitly convert a scalar to a vector (assuming
218 * the BASE<T> allows it).
219 */
220 friend inline
Mathias Agopian595ea772013-08-21 23:10:41 -0700221 BASE<T> PURE operator *(const BASE<T>& lv, const BASE<T>& rv) {
222 return BASE<T>(lv) *= rv;
223 }
224 friend inline
225 BASE<T> PURE operator /(const BASE<T>& lv, const BASE<T>& rv) {
226 return BASE<T>(lv) /= rv;
227 }
228};
229
230/*
231 * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
232 *
233 * BASE only needs to implement operator[] and size().
234 * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
235 * get all the functionality here.
236 *
237 * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
238 */
239template <template<typename T> class BASE, typename T>
240class TVecUnaryOperators {
241public:
242 BASE<T>& operator ++ () {
243 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
244 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
245 ++rhs[i];
246 }
247 return rhs;
248 }
249 BASE<T>& operator -- () {
250 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
251 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
252 --rhs[i];
253 }
254 return rhs;
255 }
256 BASE<T> operator - () const {
257 BASE<T> r(BASE<T>::NO_INIT);
258 BASE<T> const& rv(static_cast<BASE<T> const&>(*this));
259 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
260 r[i] = -rv[i];
261 }
262 return r;
263 }
264};
265
266
267/*
268 * TVecComparisonOperators implements relational/comparison operators
269 * on a vector of type BASE<T>.
270 *
271 * BASE only needs to implement operator[] and size().
272 * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
273 * get all the functionality here.
274 */
275template <template<typename T> class BASE, typename T>
276class TVecComparisonOperators {
277public:
278 /*
279 * NOTE: the functions below ARE NOT member methods. They are friend functions
280 * with they definition inlined with their declaration. This makes these
281 * template functions available to the compiler when (and only when) this class
282 * is instantiated, at which point they're only templated on the 2nd parameter
283 * (the first one, BASE<T> being known).
284 */
285 template<typename RT>
286 friend inline
287 bool PURE operator ==(const BASE<T>& lv, const BASE<RT>& rv) {
288 for (size_t i = 0; i < BASE<T>::size(); i++)
289 if (lv[i] != rv[i])
290 return false;
291 return true;
292 }
293
294 template<typename RT>
295 friend inline
296 bool PURE operator !=(const BASE<T>& lv, const BASE<RT>& rv) {
297 return !operator ==(lv, rv);
298 }
299
300 template<typename RT>
301 friend inline
302 bool PURE operator >(const BASE<T>& lv, const BASE<RT>& rv) {
303 for (size_t i = 0; i < BASE<T>::size(); i++)
304 if (lv[i] <= rv[i])
305 return false;
306 return true;
307 }
308
309 template<typename RT>
310 friend inline
311 bool PURE operator <=(const BASE<T>& lv, const BASE<RT>& rv) {
312 return !(lv > rv);
313 }
314
315 template<typename RT>
316 friend inline
317 bool PURE operator <(const BASE<T>& lv, const BASE<RT>& rv) {
318 for (size_t i = 0; i < BASE<T>::size(); i++)
319 if (lv[i] >= rv[i])
320 return false;
321 return true;
322 }
323
324 template<typename RT>
325 friend inline
326 bool PURE operator >=(const BASE<T>& lv, const BASE<RT>& rv) {
327 return !(lv < rv);
328 }
329};
330
331
332/*
333 * TVecFunctions implements functions on a vector of type BASE<T>.
334 *
335 * BASE only needs to implement operator[] and size().
336 * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
337 * get all the functionality here.
338 */
339template <template<typename T> class BASE, typename T>
340class TVecFunctions {
341public:
342 /*
343 * NOTE: the functions below ARE NOT member methods. They are friend functions
344 * with they definition inlined with their declaration. This makes these
345 * template functions available to the compiler when (and only when) this class
346 * is instantiated, at which point they're only templated on the 2nd parameter
347 * (the first one, BASE<T> being known).
348 */
349 template<typename RT>
350 friend inline
351 T PURE dot(const BASE<T>& lv, const BASE<RT>& rv) {
352 T r(0);
353 for (size_t i = 0; i < BASE<T>::size(); i++)
354 r += lv[i]*rv[i];
355 return r;
356 }
357
358 friend inline
359 T PURE length(const BASE<T>& lv) {
360 return sqrt( dot(lv, lv) );
361 }
362
363 template<typename RT>
364 friend inline
365 T PURE distance(const BASE<T>& lv, const BASE<RT>& rv) {
366 return length(rv - lv);
367 }
368
369 friend inline
370 BASE<T> PURE normalize(const BASE<T>& lv) {
371 return lv * (1 / length(lv));
372 }
373};
374
375#undef PURE
376
377// -------------------------------------------------------------------------------------
378}; // namespace android
379
380
381#endif /* UI_TVEC_HELPERS_H */