1595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/*
2595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Copyright 2013 The Android Open Source Project
3595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *
4595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License");
5595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * you may not use this file except in compliance with the License.
6595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * You may obtain a copy of the License at
7595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *
8595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *      http://www.apache.org/licenses/LICENSE-2.0
9595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *
10595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Unless required by applicable law or agreed to in writing, software
11595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS,
12595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * See the License for the specific language governing permissions and
14595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * limitations under the License.
15595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */
16595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
17595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#ifndef TVEC_IMPLEMENTATION
18595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#error "Don't include TVecHelpers.h directly. use ui/vec*.h instead"
19595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#else
20595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#undef TVEC_IMPLEMENTATION
21595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#endif
22595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
23595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
24595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#ifndef UI_TVEC_HELPERS_H
25595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#define UI_TVEC_HELPERS_H
26595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
27595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#include <stdint.h>
28595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#include <sys/types.h>
29595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
30595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#define PURE __attribute__((pure))
31595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
32595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiannamespace android {
33595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian// -------------------------------------------------------------------------------------
34595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
35595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/*
36595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * No user serviceable parts here.
37595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *
38595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Don't use this file directly, instead include ui/vec{2|3|4}.h
39595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */
40595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
41595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/*
42595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * This class casts itself into anything and assign itself from anything!
43595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Use with caution!
44595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */
45595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate <typename TYPE>
46595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianstruct Impersonator {
47595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    Impersonator& operator = (const TYPE& rhs) {
48595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        reinterpret_cast<TYPE&>(*this) = rhs;
49595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return *this;
50595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
51595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    operator TYPE& () {
52595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return reinterpret_cast<TYPE&>(*this);
53595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
54595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    operator TYPE const& () const {
55595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return reinterpret_cast<TYPE const&>(*this);
56595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
57595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian};
58595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
59595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/*
601d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
61595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * operators on a vector of type BASE<T>.
62595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *
63595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * BASE only needs to implement operator[] and size().
641d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
65595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * get all the functionality here.
66595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */
67595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
68595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate <template<typename T> class BASE, typename T>
691d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianclass TVecAddOperators {
70595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianpublic:
71595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    /* compound assignment from a another vector of the same size but different
72595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * element type.
73595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     */
74595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template <typename OTHER>
75595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T>& operator += (const BASE<OTHER>& v) {
76595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
77595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
78595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            rhs[i] += v[i];
79595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
80595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
81595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
82595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template <typename OTHER>
83595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T>& operator -= (const BASE<OTHER>& v) {
84595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
85595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
86595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            rhs[i] -= v[i];
87595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
88595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
89595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
901d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian
911d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    /* compound assignment from a another vector of the same type.
921d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * These operators can be used for implicit conversion and  handle operations
931d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * like "vector *= scalar" by letting the compiler implicitly convert a scalar
941d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * to a vector (assuming the BASE<T> allows it).
951d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     */
961d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    BASE<T>& operator += (const BASE<T>& v) {
97595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
98595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
991d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian            rhs[i] += v[i];
100595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
101595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
102595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
1031d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    BASE<T>& operator -= (const BASE<T>& v) {
104595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
105595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
1061d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian            rhs[i] -= v[i];
107595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
108595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
109595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
110595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
1111d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    /*
1121d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * NOTE: the functions below ARE NOT member methods. They are friend functions
1131d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * with they definition inlined with their declaration. This makes these
1141d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * template functions available to the compiler when (and only when) this class
1151d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * is instantiated, at which point they're only templated on the 2nd parameter
1161d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * (the first one, BASE<T> being known).
117595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     */
1181d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian
1191d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    /* The operators below handle operation between vectors of the same side
1201d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * but of a different element type.
1211d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     */
1221d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    template<typename RT>
1231d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    friend inline
1241d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) {
1251d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian        return BASE<T>(lv) += rv;
1261d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    }
1271d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    template<typename RT>
1281d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    friend inline
1291d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) {
1301d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian        return BASE<T>(lv) -= rv;
1311d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    }
1321d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian
1331d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    /* The operators below (which are not templates once this class is instanced,
1341d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
1351d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * These handle operations like "vector * scalar" and "scalar * vector" by
1361d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * letting the compiler implicitly convert a scalar to a vector (assuming
1371d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * the BASE<T> allows it).
1381d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     */
1391d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    friend inline
1401d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) {
1411d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian        return BASE<T>(lv) += rv;
1421d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    }
1431d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    friend inline
1441d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) {
1451d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian        return BASE<T>(lv) -= rv;
1461d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    }
1471d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian};
1481d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian
1491d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopiantemplate <template<typename T> class BASE, typename T>
1501d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianclass TVecProductOperators {
1511d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianpublic:
1521d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    /* compound assignment from a another vector of the same size but different
1531d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * element type.
1541d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     */
1551d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    template <typename OTHER>
1561d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    BASE<T>& operator *= (const BASE<OTHER>& v) {
157595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
158595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
1591d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian            rhs[i] *= v[i];
160595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
161595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
162595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
1631d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    template <typename OTHER>
1641d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    BASE<T>& operator /= (const BASE<OTHER>& v) {
165595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
166595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
1671d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian            rhs[i] /= v[i];
168595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
169595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
170595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
1711d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian
1721d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian    /* compound assignment from a another vector of the same type.
1731d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * These operators can be used for implicit conversion and  handle operations
1741d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * like "vector *= scalar" by letting the compiler implicitly convert a scalar
1751d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     * to a vector (assuming the BASE<T> allows it).
1761d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian     */
177595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T>& operator *= (const BASE<T>& v) {
178595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
179595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
180595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            rhs[i] *= v[i];
181595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
182595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
183595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
184595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T>& operator /= (const BASE<T>& v) {
185595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
186595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
187595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            rhs[i] /= v[i];
188595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
189595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
190595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
191595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
192595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    /*
193595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * NOTE: the functions below ARE NOT member methods. They are friend functions
194595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * with they definition inlined with their declaration. This makes these
195595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * template functions available to the compiler when (and only when) this class
196595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * is instantiated, at which point they're only templated on the 2nd parameter
197595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * (the first one, BASE<T> being known).
198595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     */
199595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
200595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    /* The operators below handle operation between vectors of the same side
201595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * but of a different element type.
202595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     */
203595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
204595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
205595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T> PURE operator *(const BASE<T>& lv, const BASE<RT>& rv) {
206595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return BASE<T>(lv) *= rv;
207595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
208595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
209595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
210595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T> PURE operator /(const BASE<T>& lv, const BASE<RT>& rv) {
211595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return BASE<T>(lv) /= rv;
212595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
213595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
214595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    /* The operators below (which are not templates once this class is instanced,
215595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
216595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * These handle operations like "vector * scalar" and "scalar * vector" by
217595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * letting the compiler implicitly convert a scalar to a vector (assuming
218595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * the BASE<T> allows it).
219595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     */
220595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
221595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T> PURE operator *(const BASE<T>& lv, const BASE<T>& rv) {
222595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return BASE<T>(lv) *= rv;
223595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
224595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
225595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T> PURE operator /(const BASE<T>& lv, const BASE<T>& rv) {
226595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return BASE<T>(lv) /= rv;
227595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
228595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian};
229595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
230595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/*
231595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
232595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *
233595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * BASE only needs to implement operator[] and size().
234595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
235595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * get all the functionality here.
236595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *
237595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
238595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */
239595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate <template<typename T> class BASE, typename T>
240595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianclass TVecUnaryOperators {
241595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianpublic:
242595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T>& operator ++ () {
243595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
244595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
245595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            ++rhs[i];
246595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
247595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
248595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
249595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T>& operator -- () {
250595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T>& rhs = static_cast<BASE<T>&>(*this);
251595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
252595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            --rhs[i];
253595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
254595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return rhs;
255595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
256595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T> operator - () const {
257595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T> r(BASE<T>::NO_INIT);
258595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        BASE<T> const& rv(static_cast<BASE<T> const&>(*this));
259595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i=0 ; i<BASE<T>::size() ; i++) {
260595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            r[i] = -rv[i];
261595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        }
262595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return r;
263595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
264595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian};
265595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
266595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
267595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/*
268595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * TVecComparisonOperators implements relational/comparison operators
269595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * on a vector of type BASE<T>.
270595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *
271595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * BASE only needs to implement operator[] and size().
272595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
273595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * get all the functionality here.
274595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */
275595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate <template<typename T> class BASE, typename T>
276595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianclass TVecComparisonOperators {
277595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianpublic:
278595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    /*
279595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * NOTE: the functions below ARE NOT member methods. They are friend functions
280595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * with they definition inlined with their declaration. This makes these
281595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * template functions available to the compiler when (and only when) this class
282595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * is instantiated, at which point they're only templated on the 2nd parameter
283595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * (the first one, BASE<T> being known).
284595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     */
285595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
286595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
287595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    bool PURE operator ==(const BASE<T>& lv, const BASE<RT>& rv) {
288595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i = 0; i < BASE<T>::size(); i++)
289595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            if (lv[i] != rv[i])
290595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian                return false;
291595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return true;
292595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
293595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
294595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
295595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
296595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    bool PURE operator !=(const BASE<T>& lv, const BASE<RT>& rv) {
297595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return !operator ==(lv, rv);
298595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
299595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
300595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
301595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
302595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    bool PURE operator >(const BASE<T>& lv, const BASE<RT>& rv) {
303595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i = 0; i < BASE<T>::size(); i++)
304595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            if (lv[i] <= rv[i])
305595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian                return false;
306595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return true;
307595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
308595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
309595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
310595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
311595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    bool PURE operator <=(const BASE<T>& lv, const BASE<RT>& rv) {
312595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return !(lv > rv);
313595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
314595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
315595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
316595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
317595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    bool PURE operator <(const BASE<T>& lv, const BASE<RT>& rv) {
318595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i = 0; i < BASE<T>::size(); i++)
319595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            if (lv[i] >= rv[i])
320595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian                return false;
321595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return true;
322595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
323595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
324595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
325595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
326595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    bool PURE operator >=(const BASE<T>& lv, const BASE<RT>& rv) {
327595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return !(lv < rv);
328595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
329595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian};
330595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
331595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
332595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/*
333595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * TVecFunctions implements functions on a vector of type BASE<T>.
334595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian *
335595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * BASE only needs to implement operator[] and size().
336595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
337595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * get all the functionality here.
338595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */
339595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiantemplate <template<typename T> class BASE, typename T>
340595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianclass TVecFunctions {
341595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianpublic:
342595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    /*
343595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * NOTE: the functions below ARE NOT member methods. They are friend functions
344595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * with they definition inlined with their declaration. This makes these
345595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * template functions available to the compiler when (and only when) this class
346595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * is instantiated, at which point they're only templated on the 2nd parameter
347595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     * (the first one, BASE<T> being known).
348595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian     */
349595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
350595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
351595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    T PURE dot(const BASE<T>& lv, const BASE<RT>& rv) {
352595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        T r(0);
353595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        for (size_t i = 0; i < BASE<T>::size(); i++)
354595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian            r += lv[i]*rv[i];
355595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return r;
356595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
357595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
358595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
359595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    T PURE length(const BASE<T>& lv) {
360595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return sqrt( dot(lv, lv) );
361595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
362595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
363595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    template<typename RT>
364595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
365595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    T PURE distance(const BASE<T>& lv, const BASE<RT>& rv) {
366595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return length(rv - lv);
367595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
368595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
369595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    friend inline
370595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    BASE<T> PURE normalize(const BASE<T>& lv) {
371595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian        return lv * (1 / length(lv));
372595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian    }
373595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian};
374595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
375595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#undef PURE
376595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
377595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian// -------------------------------------------------------------------------------------
378595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian}; // namespace android
379595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
380595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian
381595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#endif /* UI_TVEC_HELPERS_H */
382