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