blob: 081c69ce45057a3a98ba1c6838a93ba1ba2d247b [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/*
60 * TVecArithmeticOperators implements basic arithmetic and basic compound assignments
61 * operators on a vector of type BASE<T>.
62 *
63 * BASE only needs to implement operator[] and size().
64 * By simply inheriting from TVecArithmeticOperators<BASE, T> BASE will automatically
65 * get all the functionality here.
66 */
67
68template <template<typename T> class BASE, typename T>
69class TVecArithmeticOperators {
70public:
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 }
90 template <typename OTHER>
91 BASE<T>& operator *= (const BASE<OTHER>& v) {
92 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
93 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
94 rhs[i] *= v[i];
95 }
96 return rhs;
97 }
98 template <typename OTHER>
99 BASE<T>& operator /= (const BASE<OTHER>& v) {
100 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
101 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
102 rhs[i] /= v[i];
103 }
104 return rhs;
105 }
106
107 /* compound assignment from a another vector of the same type.
108 * These operators can be used for implicit conversion and handle operations
109 * like "vector *= scalar" by letting the compiler implicitly convert a scalar
110 * to a vector (assuming the BASE<T> allows it).
111 */
112 BASE<T>& operator += (const BASE<T>& v) {
113 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
114 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
115 rhs[i] += v[i];
116 }
117 return rhs;
118 }
119 BASE<T>& operator -= (const BASE<T>& v) {
120 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
121 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
122 rhs[i] -= v[i];
123 }
124 return rhs;
125 }
126 BASE<T>& operator *= (const BASE<T>& v) {
127 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
128 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
129 rhs[i] *= v[i];
130 }
131 return rhs;
132 }
133 BASE<T>& operator /= (const BASE<T>& v) {
134 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
135 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
136 rhs[i] /= v[i];
137 }
138 return rhs;
139 }
140
141 /*
142 * NOTE: the functions below ARE NOT member methods. They are friend functions
143 * with they definition inlined with their declaration. This makes these
144 * template functions available to the compiler when (and only when) this class
145 * is instantiated, at which point they're only templated on the 2nd parameter
146 * (the first one, BASE<T> being known).
147 */
148
149 /* The operators below handle operation between vectors of the same side
150 * but of a different element type.
151 */
152 template<typename RT>
153 friend inline
154 BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) {
155 return BASE<T>(lv) += rv;
156 }
157 template<typename RT>
158 friend inline
159 BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) {
160 return BASE<T>(lv) -= rv;
161 }
162 template<typename RT>
163 friend inline
164 BASE<T> PURE operator *(const BASE<T>& lv, const BASE<RT>& rv) {
165 return BASE<T>(lv) *= rv;
166 }
167 template<typename RT>
168 friend inline
169 BASE<T> PURE operator /(const BASE<T>& lv, const BASE<RT>& rv) {
170 return BASE<T>(lv) /= rv;
171 }
172
173 /* The operators below (which are not templates once this class is instanced,
174 * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
175 * These handle operations like "vector * scalar" and "scalar * vector" by
176 * letting the compiler implicitly convert a scalar to a vector (assuming
177 * the BASE<T> allows it).
178 */
179 friend inline
180 BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) {
181 return BASE<T>(lv) += rv;
182 }
183 friend inline
184 BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) {
185 return BASE<T>(lv) -= rv;
186 }
187 friend inline
188 BASE<T> PURE operator *(const BASE<T>& lv, const BASE<T>& rv) {
189 return BASE<T>(lv) *= rv;
190 }
191 friend inline
192 BASE<T> PURE operator /(const BASE<T>& lv, const BASE<T>& rv) {
193 return BASE<T>(lv) /= rv;
194 }
195};
196
197/*
198 * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
199 *
200 * BASE only needs to implement operator[] and size().
201 * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
202 * get all the functionality here.
203 *
204 * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
205 */
206template <template<typename T> class BASE, typename T>
207class TVecUnaryOperators {
208public:
209 BASE<T>& operator ++ () {
210 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
211 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
212 ++rhs[i];
213 }
214 return rhs;
215 }
216 BASE<T>& operator -- () {
217 BASE<T>& rhs = static_cast<BASE<T>&>(*this);
218 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
219 --rhs[i];
220 }
221 return rhs;
222 }
223 BASE<T> operator - () const {
224 BASE<T> r(BASE<T>::NO_INIT);
225 BASE<T> const& rv(static_cast<BASE<T> const&>(*this));
226 for (size_t i=0 ; i<BASE<T>::size() ; i++) {
227 r[i] = -rv[i];
228 }
229 return r;
230 }
231};
232
233
234/*
235 * TVecComparisonOperators implements relational/comparison operators
236 * on a vector of type BASE<T>.
237 *
238 * BASE only needs to implement operator[] and size().
239 * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
240 * get all the functionality here.
241 */
242template <template<typename T> class BASE, typename T>
243class TVecComparisonOperators {
244public:
245 /*
246 * NOTE: the functions below ARE NOT member methods. They are friend functions
247 * with they definition inlined with their declaration. This makes these
248 * template functions available to the compiler when (and only when) this class
249 * is instantiated, at which point they're only templated on the 2nd parameter
250 * (the first one, BASE<T> being known).
251 */
252 template<typename RT>
253 friend inline
254 bool PURE operator ==(const BASE<T>& lv, const BASE<RT>& rv) {
255 for (size_t i = 0; i < BASE<T>::size(); i++)
256 if (lv[i] != rv[i])
257 return false;
258 return true;
259 }
260
261 template<typename RT>
262 friend inline
263 bool PURE operator !=(const BASE<T>& lv, const BASE<RT>& rv) {
264 return !operator ==(lv, rv);
265 }
266
267 template<typename RT>
268 friend inline
269 bool PURE operator >(const BASE<T>& lv, const BASE<RT>& rv) {
270 for (size_t i = 0; i < BASE<T>::size(); i++)
271 if (lv[i] <= rv[i])
272 return false;
273 return true;
274 }
275
276 template<typename RT>
277 friend inline
278 bool PURE operator <=(const BASE<T>& lv, const BASE<RT>& rv) {
279 return !(lv > rv);
280 }
281
282 template<typename RT>
283 friend inline
284 bool PURE operator <(const BASE<T>& lv, const BASE<RT>& rv) {
285 for (size_t i = 0; i < BASE<T>::size(); i++)
286 if (lv[i] >= rv[i])
287 return false;
288 return true;
289 }
290
291 template<typename RT>
292 friend inline
293 bool PURE operator >=(const BASE<T>& lv, const BASE<RT>& rv) {
294 return !(lv < rv);
295 }
296};
297
298
299/*
300 * TVecFunctions implements functions on a vector of type BASE<T>.
301 *
302 * BASE only needs to implement operator[] and size().
303 * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
304 * get all the functionality here.
305 */
306template <template<typename T> class BASE, typename T>
307class TVecFunctions {
308public:
309 /*
310 * NOTE: the functions below ARE NOT member methods. They are friend functions
311 * with they definition inlined with their declaration. This makes these
312 * template functions available to the compiler when (and only when) this class
313 * is instantiated, at which point they're only templated on the 2nd parameter
314 * (the first one, BASE<T> being known).
315 */
316 template<typename RT>
317 friend inline
318 T PURE dot(const BASE<T>& lv, const BASE<RT>& rv) {
319 T r(0);
320 for (size_t i = 0; i < BASE<T>::size(); i++)
321 r += lv[i]*rv[i];
322 return r;
323 }
324
325 friend inline
326 T PURE length(const BASE<T>& lv) {
327 return sqrt( dot(lv, lv) );
328 }
329
330 template<typename RT>
331 friend inline
332 T PURE distance(const BASE<T>& lv, const BASE<RT>& rv) {
333 return length(rv - lv);
334 }
335
336 friend inline
337 BASE<T> PURE normalize(const BASE<T>& lv) {
338 return lv * (1 / length(lv));
339 }
340};
341
342#undef PURE
343
344// -------------------------------------------------------------------------------------
345}; // namespace android
346
347
348#endif /* UI_TVEC_HELPERS_H */