TVecHelpers.h revision 11ecb63414d2fea2f4217db8bb06a998bcf8b425
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
18#ifndef UI_TVECHELPERS_H_
19#define UI_TVECHELPERS_H_
20
21#include <math.h>
22#include <stdint.h>
23#include <sys/types.h>
24
25#include <cmath>
26#include <limits>
27#include <iostream>
28
29#define PURE __attribute__((pure))
30
31#if __cplusplus >= 201402L
32#define CONSTEXPR constexpr
33#else
34#define CONSTEXPR
35#endif
36
37namespace android {
38namespace details {
39// -------------------------------------------------------------------------------------
40
41/*
42 * No user serviceable parts here.
43 *
44 * Don't use this file directly, instead include ui/vec{2|3|4}.h
45 */
46
47/*
48 * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
49 * operators on a vector of type BASE<T>.
50 *
51 * BASE only needs to implement operator[] and size().
52 * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
53 * get all the functionality here.
54 */
55
56template <template<typename T> class VECTOR, typename T>
57class TVecAddOperators {
58public:
59    /* compound assignment from a another vector of the same size but different
60     * element type.
61     */
62    template<typename OTHER>
63    VECTOR<T>& operator +=(const VECTOR<OTHER>& v) {
64        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
65        for (size_t i = 0; i < lhs.size(); i++) {
66            lhs[i] += v[i];
67        }
68        return lhs;
69    }
70    template<typename OTHER>
71    VECTOR<T>& operator -=(const VECTOR<OTHER>& v) {
72        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
73        for (size_t i = 0; i < lhs.size(); i++) {
74            lhs[i] -= v[i];
75        }
76        return lhs;
77    }
78
79    /* compound assignment from a another vector of the same type.
80     * These operators can be used for implicit conversion and  handle operations
81     * like "vector *= scalar" by letting the compiler implicitly convert a scalar
82     * to a vector (assuming the BASE<T> allows it).
83     */
84    VECTOR<T>& operator +=(const VECTOR<T>& v) {
85        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
86        for (size_t i = 0; i < lhs.size(); i++) {
87            lhs[i] += v[i];
88        }
89        return lhs;
90    }
91    VECTOR<T>& operator -=(const VECTOR<T>& v) {
92        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
93        for (size_t i = 0; i < lhs.size(); i++) {
94            lhs[i] -= v[i];
95        }
96        return lhs;
97    }
98
99    /*
100     * NOTE: the functions below ARE NOT member methods. They are friend functions
101     * with they definition inlined with their declaration. This makes these
102     * template functions available to the compiler when (and only when) this class
103     * is instantiated, at which point they're only templated on the 2nd parameter
104     * (the first one, BASE<T> being known).
105     */
106
107    /* The operators below handle operation between vectors of the same size
108     * but of a different element type.
109     */
110    template<typename RT>
111    friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<RT>& rv) {
112        // don't pass lv by reference because we need a copy anyways
113        return lv += rv;
114    }
115    template<typename RT>
116    friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<RT>& rv) {
117        // don't pass lv by reference because we need a copy anyways
118        return lv -= rv;
119    }
120
121    /* The operators below (which are not templates once this class is instanced,
122     * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
123     * These handle operations like "vector + scalar" and "scalar + vector" by
124     * letting the compiler implicitly convert a scalar to a vector (assuming
125     * the BASE<T> allows it).
126     */
127    friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<T>& rv) {
128        // don't pass lv by reference because we need a copy anyways
129        return lv += rv;
130    }
131    friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<T>& rv) {
132        // don't pass lv by reference because we need a copy anyways
133        return lv -= rv;
134    }
135};
136
137template<template<typename T> class VECTOR, typename T>
138class TVecProductOperators {
139public:
140    /* compound assignment from a another vector of the same size but different
141     * element type.
142     */
143    template<typename OTHER>
144    VECTOR<T>& operator *=(const VECTOR<OTHER>& v) {
145        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
146        for (size_t i = 0; i < lhs.size(); i++) {
147            lhs[i] *= v[i];
148        }
149        return lhs;
150    }
151    template<typename OTHER>
152    VECTOR<T>& operator /=(const VECTOR<OTHER>& v) {
153        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
154        for (size_t i = 0; i < lhs.size(); i++) {
155            lhs[i] /= v[i];
156        }
157        return lhs;
158    }
159
160    /* compound assignment from a another vector of the same type.
161     * These operators can be used for implicit conversion and  handle operations
162     * like "vector *= scalar" by letting the compiler implicitly convert a scalar
163     * to a vector (assuming the BASE<T> allows it).
164     */
165    VECTOR<T>& operator *=(const VECTOR<T>& v) {
166        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
167        for (size_t i = 0; i < lhs.size(); i++) {
168            lhs[i] *= v[i];
169        }
170        return lhs;
171    }
172    VECTOR<T>& operator /=(const VECTOR<T>& v) {
173        VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
174        for (size_t i = 0; i < lhs.size(); i++) {
175            lhs[i] /= v[i];
176        }
177        return lhs;
178    }
179
180    /*
181     * NOTE: the functions below ARE NOT member methods. They are friend functions
182     * with they definition inlined with their declaration. This makes these
183     * template functions available to the compiler when (and only when) this class
184     * is instantiated, at which point they're only templated on the 2nd parameter
185     * (the first one, BASE<T> being known).
186     */
187
188    /* The operators below handle operation between vectors of the same size
189     * but of a different element type.
190     */
191    template<typename RT>
192    friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<RT>& rv) {
193        // don't pass lv by reference because we need a copy anyways
194        return lv *= rv;
195    }
196    template<typename RT>
197    friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<RT>& rv) {
198        // don't pass lv by reference because we need a copy anyways
199        return lv /= rv;
200    }
201
202    /* The operators below (which are not templates once this class is instanced,
203     * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
204     * These handle operations like "vector * scalar" and "scalar * vector" by
205     * letting the compiler implicitly convert a scalar to a vector (assuming
206     * the BASE<T> allows it).
207     */
208    friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<T>& rv) {
209        // don't pass lv by reference because we need a copy anyways
210        return lv *= rv;
211    }
212    friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<T>& rv) {
213        // don't pass lv by reference because we need a copy anyways
214        return lv /= rv;
215    }
216};
217
218/*
219 * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
220 *
221 * BASE only needs to implement operator[] and size().
222 * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
223 * get all the functionality here.
224 *
225 * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
226 */
227template<template<typename T> class VECTOR, typename T>
228class TVecUnaryOperators {
229public:
230    VECTOR<T>& operator ++() {
231        VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
232        for (size_t i = 0; i < rhs.size(); i++) {
233            ++rhs[i];
234        }
235        return rhs;
236    }
237
238    VECTOR<T>& operator --() {
239        VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
240        for (size_t i = 0; i < rhs.size(); i++) {
241            --rhs[i];
242        }
243        return rhs;
244    }
245
246    CONSTEXPR VECTOR<T> operator -() const {
247        VECTOR<T> r(VECTOR<T>::NO_INIT);
248        VECTOR<T> const& rv(static_cast<VECTOR<T> const&>(*this));
249        for (size_t i = 0; i < r.size(); i++) {
250            r[i] = -rv[i];
251        }
252        return r;
253    }
254};
255
256/*
257 * TVecComparisonOperators implements relational/comparison operators
258 * on a vector of type BASE<T>.
259 *
260 * BASE only needs to implement operator[] and size().
261 * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
262 * get all the functionality here.
263 */
264template<template<typename T> class VECTOR, typename T>
265class TVecComparisonOperators {
266public:
267    /*
268     * NOTE: the functions below ARE NOT member methods. They are friend functions
269     * with they definition inlined with their declaration. This makes these
270     * template functions available to the compiler when (and only when) this class
271     * is instantiated, at which point they're only templated on the 2nd parameter
272     * (the first one, BASE<T> being known).
273     */
274    template<typename RT>
275    friend inline
276    bool PURE operator ==(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
277        for (size_t i = 0; i < lv.size(); i++)
278            if (lv[i] != rv[i])
279                return false;
280        return true;
281    }
282
283    template<typename RT>
284    friend inline
285    bool PURE operator !=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
286        return !operator ==(lv, rv);
287    }
288
289    template<typename RT>
290    friend inline
291    bool PURE operator >(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
292        for (size_t i = 0; i < lv.size(); i++) {
293            if (lv[i] == rv[i]) {
294                continue;
295            }
296            return lv[i] > rv[i];
297        }
298        return false;
299    }
300
301    template<typename RT>
302    friend inline
303    constexpr bool PURE operator <=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
304        return !(lv > rv);
305    }
306
307    template<typename RT>
308    friend inline
309    bool PURE operator <(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
310        for (size_t i = 0; i < lv.size(); i++) {
311            if (lv[i] == rv[i]) {
312                continue;
313            }
314            return lv[i] < rv[i];
315        }
316        return false;
317    }
318
319    template<typename RT>
320    friend inline
321    constexpr bool PURE operator >=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
322        return !(lv < rv);
323    }
324
325    template<typename RT>
326    friend inline
327    constexpr VECTOR<bool> PURE equal(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
328        VECTOR<bool> r;
329        for (size_t i = 0; i < lv.size(); i++) {
330            r[i] = lv[i] == rv[i];
331        }
332        return r;
333    }
334
335    template<typename RT>
336    friend inline
337    constexpr VECTOR<bool> PURE notEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
338        VECTOR<bool> r;
339        for (size_t i = 0; i < lv.size(); i++) {
340            r[i] = lv[i] != rv[i];
341        }
342        return r;
343    }
344
345    template<typename RT>
346    friend inline
347    constexpr VECTOR<bool> PURE lessThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
348        VECTOR<bool> r;
349        for (size_t i = 0; i < lv.size(); i++) {
350            r[i] = lv[i] < rv[i];
351        }
352        return r;
353    }
354
355    template<typename RT>
356    friend inline
357    constexpr VECTOR<bool> PURE lessThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
358        VECTOR<bool> r;
359        for (size_t i = 0; i < lv.size(); i++) {
360            r[i] = lv[i] <= rv[i];
361        }
362        return r;
363    }
364
365    template<typename RT>
366    friend inline
367    constexpr VECTOR<bool> PURE greaterThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
368        VECTOR<bool> r;
369        for (size_t i = 0; i < lv.size(); i++) {
370            r[i] = lv[i] > rv[i];
371        }
372        return r;
373    }
374
375    template<typename RT>
376    friend inline
377    constexpr VECTOR<bool> PURE greaterThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
378        VECTOR<bool> r;
379        for (size_t i = 0; i < lv.size(); i++) {
380            r[i] = lv[i] >= rv[i];
381        }
382        return r;
383    }
384};
385
386/*
387 * TVecFunctions implements functions on a vector of type BASE<T>.
388 *
389 * BASE only needs to implement operator[] and size().
390 * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
391 * get all the functionality here.
392 */
393template<template<typename T> class VECTOR, typename T>
394class TVecFunctions {
395public:
396    /*
397     * NOTE: the functions below ARE NOT member methods. They are friend functions
398     * with they definition inlined with their declaration. This makes these
399     * template functions available to the compiler when (and only when) this class
400     * is instantiated, at which point they're only templated on the 2nd parameter
401     * (the first one, BASE<T> being known).
402     */
403    template<typename RT>
404    friend inline CONSTEXPR T PURE dot(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
405        T r(0);
406        for (size_t i = 0; i < lv.size(); i++) {
407            //r = std::fma(lv[i], rv[i], r);
408            r += lv[i] * rv[i];
409        }
410        return r;
411    }
412
413    friend inline constexpr T PURE norm(const VECTOR<T>& lv) {
414        return std::sqrt(dot(lv, lv));
415    }
416
417    friend inline constexpr T PURE length(const VECTOR<T>& lv) {
418        return norm(lv);
419    }
420
421    friend inline constexpr T PURE norm2(const VECTOR<T>& lv) {
422        return dot(lv, lv);
423    }
424
425    friend inline constexpr T PURE length2(const VECTOR<T>& lv) {
426        return norm2(lv);
427    }
428
429    template<typename RT>
430    friend inline constexpr T PURE distance(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
431        return length(rv - lv);
432    }
433
434    template<typename RT>
435    friend inline constexpr T PURE distance2(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
436        return length2(rv - lv);
437    }
438
439    friend inline constexpr VECTOR<T> PURE normalize(const VECTOR<T>& lv) {
440        return lv * (T(1) / length(lv));
441    }
442
443    friend inline constexpr VECTOR<T> PURE rcp(VECTOR<T> v) {
444        return T(1) / v;
445    }
446
447    friend inline CONSTEXPR VECTOR<T> PURE abs(VECTOR<T> v) {
448        for (size_t i = 0; i < v.size(); i++) {
449            v[i] = std::abs(v[i]);
450        }
451        return v;
452    }
453
454    friend inline CONSTEXPR VECTOR<T> PURE floor(VECTOR<T> v) {
455        for (size_t i = 0; i < v.size(); i++) {
456            v[i] = std::floor(v[i]);
457        }
458        return v;
459    }
460
461    friend inline CONSTEXPR VECTOR<T> PURE ceil(VECTOR<T> v) {
462        for (size_t i = 0; i < v.size(); i++) {
463            v[i] = std::ceil(v[i]);
464        }
465        return v;
466    }
467
468    friend inline CONSTEXPR VECTOR<T> PURE round(VECTOR<T> v) {
469        for (size_t i = 0; i < v.size(); i++) {
470            v[i] = std::round(v[i]);
471        }
472        return v;
473    }
474
475    friend inline CONSTEXPR VECTOR<T> PURE inversesqrt(VECTOR<T> v) {
476        for (size_t i = 0; i < v.size(); i++) {
477            v[i] = T(1) / std::sqrt(v[i]);
478        }
479        return v;
480    }
481
482    friend inline CONSTEXPR VECTOR<T> PURE sqrt(VECTOR<T> v) {
483        for (size_t i = 0; i < v.size(); i++) {
484            v[i] = std::sqrt(v[i]);
485        }
486        return v;
487    }
488
489    friend inline CONSTEXPR VECTOR<T> PURE pow(VECTOR<T> v, T p) {
490        for (size_t i = 0; i < v.size(); i++) {
491            v[i] = std::pow(v[i], p);
492        }
493        return v;
494    }
495
496    friend inline CONSTEXPR VECTOR<T> PURE saturate(const VECTOR<T>& lv) {
497        return clamp(lv, T(0), T(1));
498    }
499
500    friend inline CONSTEXPR VECTOR<T> PURE clamp(VECTOR<T> v, T min, T max) {
501        for (size_t i = 0; i< v.size(); i++) {
502            v[i] = std::min(max, std::max(min, v[i]));
503        }
504        return v;
505    }
506
507    friend inline CONSTEXPR VECTOR<T> PURE fma(const VECTOR<T>& lv, const VECTOR<T>& rv, VECTOR<T> a) {
508        for (size_t i = 0; i<lv.size(); i++) {
509            //a[i] = std::fma(lv[i], rv[i], a[i]);
510            a[i] += (lv[i] * rv[i]);
511        }
512        return a;
513    }
514
515    friend inline CONSTEXPR VECTOR<T> PURE min(const VECTOR<T>& u, VECTOR<T> v) {
516        for (size_t i = 0; i < v.size(); i++) {
517            v[i] = std::min(u[i], v[i]);
518        }
519        return v;
520    }
521
522    friend inline CONSTEXPR VECTOR<T> PURE max(const VECTOR<T>& u, VECTOR<T> v) {
523        for (size_t i = 0; i < v.size(); i++) {
524            v[i] = std::max(u[i], v[i]);
525        }
526        return v;
527    }
528
529    friend inline CONSTEXPR T PURE max(const VECTOR<T>& v) {
530        T r(std::numeric_limits<T>::lowest());
531        for (size_t i = 0; i < v.size(); i++) {
532            r = std::max(r, v[i]);
533        }
534        return r;
535    }
536
537    friend inline CONSTEXPR T PURE min(const VECTOR<T>& v) {
538        T r(std::numeric_limits<T>::max());
539        for (size_t i = 0; i < v.size(); i++) {
540            r = std::min(r, v[i]);
541        }
542        return r;
543    }
544
545    friend inline CONSTEXPR VECTOR<T> PURE apply(VECTOR<T> v, const std::function<T(T)>& f) {
546        for (size_t i = 0; i < v.size(); i++) {
547            v[i] = f(v[i]);
548        }
549        return v;
550    }
551
552    friend inline CONSTEXPR bool PURE any(const VECTOR<T>& v) {
553        for (size_t i = 0; i < v.size(); i++) {
554            if (v[i] != T(0)) return true;
555        }
556        return false;
557    }
558
559    friend inline CONSTEXPR bool PURE all(const VECTOR<T>& v) {
560        bool result = true;
561        for (size_t i = 0; i < v.size(); i++) {
562            result &= (v[i] != T(0));
563        }
564        return result;
565    }
566
567    template<typename R>
568    friend inline CONSTEXPR VECTOR<R> PURE map(VECTOR<T> v, const std::function<R(T)>& f) {
569        VECTOR<R> result;
570        for (size_t i = 0; i < v.size(); i++) {
571            result[i] = f(v[i]);
572        }
573        return result;
574    }
575};
576
577/*
578 * TVecDebug implements functions on a vector of type BASE<T>.
579 *
580 * BASE only needs to implement operator[] and size().
581 * By simply inheriting from TVecDebug<BASE, T> BASE will automatically
582 * get all the functionality here.
583 */
584template<template<typename T> class VECTOR, typename T>
585class TVecDebug {
586public:
587    /*
588     * NOTE: the functions below ARE NOT member methods. They are friend functions
589     * with they definition inlined with their declaration. This makes these
590     * template functions available to the compiler when (and only when) this class
591     * is instantiated, at which point they're only templated on the 2nd parameter
592     * (the first one, BASE<T> being known).
593     */
594    friend std::ostream& operator<<(std::ostream& stream, const VECTOR<T>& v) {
595        stream << "< ";
596        for (size_t i = 0; i < v.size() - 1; i++) {
597            stream << T(v[i]) << ", ";
598        }
599        stream << T(v[v.size() - 1]) << " >";
600        return stream;
601    }
602};
603
604#undef CONSTEXPR
605#undef PURE
606
607// -------------------------------------------------------------------------------------
608}  // namespace details
609}  // namespace android
610
611
612#endif  // UI_TVECHELPERS_H_
613