1 /*
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 
32 namespace 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  */
45 template <typename TYPE>
46 struct 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  * TVec{Add|Product}Operators 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 TVec{Add|Product}Operators<BASE, T> BASE will automatically
65  * get all the functionality here.
66  */
67 
68 template <template<typename T> class BASE, typename T>
69 class TVecAddOperators {
70 public:
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 
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     }
110 
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 
149 template <template<typename T> class BASE, typename T>
150 class TVecProductOperators {
151 public:
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      */
177     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
205     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
221     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  */
239 template <template<typename T> class BASE, typename T>
240 class TVecUnaryOperators {
241 public:
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  */
275 template <template<typename T> class BASE, typename T>
276 class TVecComparisonOperators {
277 public:
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  */
339 template <template<typename T> class BASE, typename T>
340 class TVecFunctions {
341 public:
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
dot(const BASE<T> & lv,const BASE<RT> & rv)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
length(const BASE<T> & lv)359     T PURE length(const BASE<T>& lv) {
360         return sqrt( dot(lv, lv) );
361     }
362 
363     template<typename RT>
364     friend inline
distance(const BASE<T> & lv,const BASE<RT> & rv)365     T PURE distance(const BASE<T>& lv, const BASE<RT>& rv) {
366         return length(rv - lv);
367     }
368 
369     friend inline
normalize(const BASE<T> & lv)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 */
382