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