TVecHelpers.h revision 595ea77f6bdb5e9d0ddd3305da7a44b56f326b2c
1/* 2 * Copyright 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef TVEC_IMPLEMENTATION 18#error "Don't include TVecHelpers.h directly. use ui/vec*.h instead" 19#else 20#undef TVEC_IMPLEMENTATION 21#endif 22 23 24#ifndef UI_TVEC_HELPERS_H 25#define UI_TVEC_HELPERS_H 26 27#include <stdint.h> 28#include <sys/types.h> 29 30#define PURE __attribute__((pure)) 31 32namespace android { 33// ------------------------------------------------------------------------------------- 34 35/* 36 * No user serviceable parts here. 37 * 38 * Don't use this file directly, instead include ui/vec{2|3|4}.h 39 */ 40 41/* 42 * This class casts itself into anything and assign itself from anything! 43 * Use with caution! 44 */ 45template <typename TYPE> 46struct Impersonator { 47 Impersonator& operator = (const TYPE& rhs) { 48 reinterpret_cast<TYPE&>(*this) = rhs; 49 return *this; 50 } 51 operator TYPE& () { 52 return reinterpret_cast<TYPE&>(*this); 53 } 54 operator TYPE const& () const { 55 return reinterpret_cast<TYPE const&>(*this); 56 } 57}; 58 59/* 60 * TVecArithmeticOperators implements basic arithmetic and basic compound assignments 61 * operators on a vector of type BASE<T>. 62 * 63 * BASE only needs to implement operator[] and size(). 64 * By simply inheriting from TVecArithmeticOperators<BASE, T> BASE will automatically 65 * get all the functionality here. 66 */ 67 68template <template<typename T> class BASE, typename T> 69class TVecArithmeticOperators { 70public: 71 /* compound assignment from a another vector of the same size but different 72 * element type. 73 */ 74 template <typename OTHER> 75 BASE<T>& operator += (const BASE<OTHER>& v) { 76 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 77 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 78 rhs[i] += v[i]; 79 } 80 return rhs; 81 } 82 template <typename OTHER> 83 BASE<T>& operator -= (const BASE<OTHER>& v) { 84 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 85 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 86 rhs[i] -= v[i]; 87 } 88 return rhs; 89 } 90 template <typename OTHER> 91 BASE<T>& operator *= (const BASE<OTHER>& v) { 92 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 93 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 94 rhs[i] *= v[i]; 95 } 96 return rhs; 97 } 98 template <typename OTHER> 99 BASE<T>& operator /= (const BASE<OTHER>& v) { 100 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 101 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 102 rhs[i] /= v[i]; 103 } 104 return rhs; 105 } 106 107 /* compound assignment from a another vector of the same type. 108 * These operators can be used for implicit conversion and handle operations 109 * like "vector *= scalar" by letting the compiler implicitly convert a scalar 110 * to a vector (assuming the BASE<T> allows it). 111 */ 112 BASE<T>& operator += (const BASE<T>& v) { 113 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 114 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 115 rhs[i] += v[i]; 116 } 117 return rhs; 118 } 119 BASE<T>& operator -= (const BASE<T>& v) { 120 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 121 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 122 rhs[i] -= v[i]; 123 } 124 return rhs; 125 } 126 BASE<T>& operator *= (const BASE<T>& v) { 127 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 128 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 129 rhs[i] *= v[i]; 130 } 131 return rhs; 132 } 133 BASE<T>& operator /= (const BASE<T>& v) { 134 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 135 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 136 rhs[i] /= v[i]; 137 } 138 return rhs; 139 } 140 141 /* 142 * NOTE: the functions below ARE NOT member methods. They are friend functions 143 * with they definition inlined with their declaration. This makes these 144 * template functions available to the compiler when (and only when) this class 145 * is instantiated, at which point they're only templated on the 2nd parameter 146 * (the first one, BASE<T> being known). 147 */ 148 149 /* The operators below handle operation between vectors of the same side 150 * but of a different element type. 151 */ 152 template<typename RT> 153 friend inline 154 BASE<T> PURE operator +(const BASE<T>& lv, const BASE<RT>& rv) { 155 return BASE<T>(lv) += rv; 156 } 157 template<typename RT> 158 friend inline 159 BASE<T> PURE operator -(const BASE<T>& lv, const BASE<RT>& rv) { 160 return BASE<T>(lv) -= rv; 161 } 162 template<typename RT> 163 friend inline 164 BASE<T> PURE operator *(const BASE<T>& lv, const BASE<RT>& rv) { 165 return BASE<T>(lv) *= rv; 166 } 167 template<typename RT> 168 friend inline 169 BASE<T> PURE operator /(const BASE<T>& lv, const BASE<RT>& rv) { 170 return BASE<T>(lv) /= rv; 171 } 172 173 /* The operators below (which are not templates once this class is instanced, 174 * i.e.: BASE<T> is known) can be used for implicit conversion on both sides. 175 * These handle operations like "vector * scalar" and "scalar * vector" by 176 * letting the compiler implicitly convert a scalar to a vector (assuming 177 * the BASE<T> allows it). 178 */ 179 friend inline 180 BASE<T> PURE operator +(const BASE<T>& lv, const BASE<T>& rv) { 181 return BASE<T>(lv) += rv; 182 } 183 friend inline 184 BASE<T> PURE operator -(const BASE<T>& lv, const BASE<T>& rv) { 185 return BASE<T>(lv) -= rv; 186 } 187 friend inline 188 BASE<T> PURE operator *(const BASE<T>& lv, const BASE<T>& rv) { 189 return BASE<T>(lv) *= rv; 190 } 191 friend inline 192 BASE<T> PURE operator /(const BASE<T>& lv, const BASE<T>& rv) { 193 return BASE<T>(lv) /= rv; 194 } 195}; 196 197/* 198 * TVecUnaryOperators implements unary operators on a vector of type BASE<T>. 199 * 200 * BASE only needs to implement operator[] and size(). 201 * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically 202 * get all the functionality here. 203 * 204 * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T> 205 */ 206template <template<typename T> class BASE, typename T> 207class TVecUnaryOperators { 208public: 209 BASE<T>& operator ++ () { 210 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 211 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 212 ++rhs[i]; 213 } 214 return rhs; 215 } 216 BASE<T>& operator -- () { 217 BASE<T>& rhs = static_cast<BASE<T>&>(*this); 218 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 219 --rhs[i]; 220 } 221 return rhs; 222 } 223 BASE<T> operator - () const { 224 BASE<T> r(BASE<T>::NO_INIT); 225 BASE<T> const& rv(static_cast<BASE<T> const&>(*this)); 226 for (size_t i=0 ; i<BASE<T>::size() ; i++) { 227 r[i] = -rv[i]; 228 } 229 return r; 230 } 231}; 232 233 234/* 235 * TVecComparisonOperators implements relational/comparison operators 236 * on a vector of type BASE<T>. 237 * 238 * BASE only needs to implement operator[] and size(). 239 * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically 240 * get all the functionality here. 241 */ 242template <template<typename T> class BASE, typename T> 243class TVecComparisonOperators { 244public: 245 /* 246 * NOTE: the functions below ARE NOT member methods. They are friend functions 247 * with they definition inlined with their declaration. This makes these 248 * template functions available to the compiler when (and only when) this class 249 * is instantiated, at which point they're only templated on the 2nd parameter 250 * (the first one, BASE<T> being known). 251 */ 252 template<typename RT> 253 friend inline 254 bool PURE operator ==(const BASE<T>& lv, const BASE<RT>& rv) { 255 for (size_t i = 0; i < BASE<T>::size(); i++) 256 if (lv[i] != rv[i]) 257 return false; 258 return true; 259 } 260 261 template<typename RT> 262 friend inline 263 bool PURE operator !=(const BASE<T>& lv, const BASE<RT>& rv) { 264 return !operator ==(lv, rv); 265 } 266 267 template<typename RT> 268 friend inline 269 bool PURE operator >(const BASE<T>& lv, const BASE<RT>& rv) { 270 for (size_t i = 0; i < BASE<T>::size(); i++) 271 if (lv[i] <= rv[i]) 272 return false; 273 return true; 274 } 275 276 template<typename RT> 277 friend inline 278 bool PURE operator <=(const BASE<T>& lv, const BASE<RT>& rv) { 279 return !(lv > rv); 280 } 281 282 template<typename RT> 283 friend inline 284 bool PURE operator <(const BASE<T>& lv, const BASE<RT>& rv) { 285 for (size_t i = 0; i < BASE<T>::size(); i++) 286 if (lv[i] >= rv[i]) 287 return false; 288 return true; 289 } 290 291 template<typename RT> 292 friend inline 293 bool PURE operator >=(const BASE<T>& lv, const BASE<RT>& rv) { 294 return !(lv < rv); 295 } 296}; 297 298 299/* 300 * TVecFunctions implements functions on a vector of type BASE<T>. 301 * 302 * BASE only needs to implement operator[] and size(). 303 * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically 304 * get all the functionality here. 305 */ 306template <template<typename T> class BASE, typename T> 307class TVecFunctions { 308public: 309 /* 310 * NOTE: the functions below ARE NOT member methods. They are friend functions 311 * with they definition inlined with their declaration. This makes these 312 * template functions available to the compiler when (and only when) this class 313 * is instantiated, at which point they're only templated on the 2nd parameter 314 * (the first one, BASE<T> being known). 315 */ 316 template<typename RT> 317 friend inline 318 T PURE dot(const BASE<T>& lv, const BASE<RT>& rv) { 319 T r(0); 320 for (size_t i = 0; i < BASE<T>::size(); i++) 321 r += lv[i]*rv[i]; 322 return r; 323 } 324 325 friend inline 326 T PURE length(const BASE<T>& lv) { 327 return sqrt( dot(lv, lv) ); 328 } 329 330 template<typename RT> 331 friend inline 332 T PURE distance(const BASE<T>& lv, const BASE<RT>& rv) { 333 return length(rv - lv); 334 } 335 336 friend inline 337 BASE<T> PURE normalize(const BASE<T>& lv) { 338 return lv * (1 / length(lv)); 339 } 340}; 341 342#undef PURE 343 344// ------------------------------------------------------------------------------------- 345}; // namespace android 346 347 348#endif /* UI_TVEC_HELPERS_H */ 349