blob: 1884608fa27c430ec4a326c0359f2b223b82f32d [file] [log] [blame]
Mathias Agopian595ea772013-08-21 23:10:41 -07001/*
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
Mathias Agopian595ea772013-08-21 23:10:41 -070017
Romain Guy5d4bae72016-11-08 09:49:25 -080018#ifndef UI_TVECHELPERS_H_
19#define UI_TVECHELPERS_H_
Mathias Agopian595ea772013-08-21 23:10:41 -070020
Romain Guy5d4bae72016-11-08 09:49:25 -080021#include <math.h>
Mathias Agopian595ea772013-08-21 23:10:41 -070022#include <stdint.h>
23#include <sys/types.h>
24
Romain Guy5d4bae72016-11-08 09:49:25 -080025#include <cmath>
26#include <limits>
27#include <iostream>
28
Mathias Agopian595ea772013-08-21 23:10:41 -070029#define PURE __attribute__((pure))
30
Romain Guycaf2ca42016-11-10 11:45:58 -080031#if __cplusplus >= 201402L
32#define CONSTEXPR constexpr
33#else
34#define CONSTEXPR
35#endif
36
Mathias Agopian595ea772013-08-21 23:10:41 -070037namespace android {
Romain Guy5d4bae72016-11-08 09:49:25 -080038namespace details {
Mathias Agopian595ea772013-08-21 23:10:41 -070039// -------------------------------------------------------------------------------------
40
41/*
42 * No user serviceable parts here.
43 *
44 * Don't use this file directly, instead include ui/vec{2|3|4}.h
45 */
46
47/*
Mathias Agopian1d4d8f92013-09-01 21:35:36 -070048 * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments
Mathias Agopian595ea772013-08-21 23:10:41 -070049 * operators on a vector of type BASE<T>.
50 *
51 * BASE only needs to implement operator[] and size().
Mathias Agopian1d4d8f92013-09-01 21:35:36 -070052 * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically
Mathias Agopian595ea772013-08-21 23:10:41 -070053 * get all the functionality here.
54 */
55
Romain Guy5d4bae72016-11-08 09:49:25 -080056template <template<typename T> class VECTOR, typename T>
Mathias Agopian1d4d8f92013-09-01 21:35:36 -070057class TVecAddOperators {
Mathias Agopian595ea772013-08-21 23:10:41 -070058public:
59 /* compound assignment from a another vector of the same size but different
60 * element type.
61 */
Romain Guy5d4bae72016-11-08 09:49:25 -080062 template<typename OTHER>
63 VECTOR<T>& operator +=(const VECTOR<OTHER>& v) {
64 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
65 for (size_t i = 0; i < lhs.size(); i++) {
66 lhs[i] += v[i];
Mathias Agopian595ea772013-08-21 23:10:41 -070067 }
Romain Guy5d4bae72016-11-08 09:49:25 -080068 return lhs;
Mathias Agopian595ea772013-08-21 23:10:41 -070069 }
Romain Guy5d4bae72016-11-08 09:49:25 -080070 template<typename OTHER>
71 VECTOR<T>& operator -=(const VECTOR<OTHER>& v) {
72 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
73 for (size_t i = 0; i < lhs.size(); i++) {
74 lhs[i] -= v[i];
Mathias Agopian595ea772013-08-21 23:10:41 -070075 }
Romain Guy5d4bae72016-11-08 09:49:25 -080076 return lhs;
Mathias Agopian595ea772013-08-21 23:10:41 -070077 }
Mathias Agopian595ea772013-08-21 23:10:41 -070078
79 /* compound assignment from a another vector of the same type.
80 * These operators can be used for implicit conversion and handle operations
81 * like "vector *= scalar" by letting the compiler implicitly convert a scalar
82 * to a vector (assuming the BASE<T> allows it).
83 */
Romain Guy5d4bae72016-11-08 09:49:25 -080084 VECTOR<T>& operator +=(const VECTOR<T>& v) {
85 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
86 for (size_t i = 0; i < lhs.size(); i++) {
87 lhs[i] += v[i];
Mathias Agopian595ea772013-08-21 23:10:41 -070088 }
Romain Guy5d4bae72016-11-08 09:49:25 -080089 return lhs;
Mathias Agopian595ea772013-08-21 23:10:41 -070090 }
Romain Guy5d4bae72016-11-08 09:49:25 -080091 VECTOR<T>& operator -=(const VECTOR<T>& v) {
92 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
93 for (size_t i = 0; i < lhs.size(); i++) {
94 lhs[i] -= v[i];
Mathias Agopian595ea772013-08-21 23:10:41 -070095 }
Romain Guy5d4bae72016-11-08 09:49:25 -080096 return lhs;
Mathias Agopian595ea772013-08-21 23:10:41 -070097 }
Mathias Agopian1d4d8f92013-09-01 21:35:36 -070098
99 /*
100 * NOTE: the functions below ARE NOT member methods. They are friend functions
101 * with they definition inlined with their declaration. This makes these
102 * template functions available to the compiler when (and only when) this class
103 * is instantiated, at which point they're only templated on the 2nd parameter
104 * (the first one, BASE<T> being known).
105 */
106
Romain Guy5d4bae72016-11-08 09:49:25 -0800107 /* The operators below handle operation between vectors of the same size
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700108 * but of a different element type.
109 */
110 template<typename RT>
Romain Guy5d4bae72016-11-08 09:49:25 -0800111 friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<RT>& rv) {
112 // don't pass lv by reference because we need a copy anyways
113 return lv += rv;
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700114 }
115 template<typename RT>
Romain Guy5d4bae72016-11-08 09:49:25 -0800116 friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<RT>& rv) {
117 // don't pass lv by reference because we need a copy anyways
118 return lv -= rv;
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700119 }
120
121 /* The operators below (which are not templates once this class is instanced,
122 * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
Romain Guy5d4bae72016-11-08 09:49:25 -0800123 * These handle operations like "vector + scalar" and "scalar + vector" by
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700124 * letting the compiler implicitly convert a scalar to a vector (assuming
125 * the BASE<T> allows it).
126 */
Romain Guy5d4bae72016-11-08 09:49:25 -0800127 friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<T>& rv) {
128 // don't pass lv by reference because we need a copy anyways
129 return lv += rv;
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700130 }
Romain Guy5d4bae72016-11-08 09:49:25 -0800131 friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<T>& rv) {
132 // don't pass lv by reference because we need a copy anyways
133 return lv -= rv;
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700134 }
135};
136
Romain Guy5d4bae72016-11-08 09:49:25 -0800137template<template<typename T> class VECTOR, typename T>
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700138class TVecProductOperators {
139public:
140 /* compound assignment from a another vector of the same size but different
141 * element type.
142 */
Romain Guy5d4bae72016-11-08 09:49:25 -0800143 template<typename OTHER>
144 VECTOR<T>& operator *=(const VECTOR<OTHER>& v) {
145 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
146 for (size_t i = 0; i < lhs.size(); i++) {
147 lhs[i] *= v[i];
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700148 }
Romain Guy5d4bae72016-11-08 09:49:25 -0800149 return lhs;
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700150 }
Romain Guy5d4bae72016-11-08 09:49:25 -0800151 template<typename OTHER>
152 VECTOR<T>& operator /=(const VECTOR<OTHER>& v) {
153 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
154 for (size_t i = 0; i < lhs.size(); i++) {
155 lhs[i] /= v[i];
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700156 }
Romain Guy5d4bae72016-11-08 09:49:25 -0800157 return lhs;
Mathias Agopian1d4d8f92013-09-01 21:35:36 -0700158 }
159
160 /* compound assignment from a another vector of the same type.
161 * These operators can be used for implicit conversion and handle operations
162 * like "vector *= scalar" by letting the compiler implicitly convert a scalar
163 * to a vector (assuming the BASE<T> allows it).
164 */
Romain Guy5d4bae72016-11-08 09:49:25 -0800165 VECTOR<T>& operator *=(const VECTOR<T>& v) {
166 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
167 for (size_t i = 0; i < lhs.size(); i++) {
168 lhs[i] *= v[i];
Mathias Agopian595ea772013-08-21 23:10:41 -0700169 }
Romain Guy5d4bae72016-11-08 09:49:25 -0800170 return lhs;
Mathias Agopian595ea772013-08-21 23:10:41 -0700171 }
Romain Guy5d4bae72016-11-08 09:49:25 -0800172 VECTOR<T>& operator /=(const VECTOR<T>& v) {
173 VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this);
174 for (size_t i = 0; i < lhs.size(); i++) {
175 lhs[i] /= v[i];
Mathias Agopian595ea772013-08-21 23:10:41 -0700176 }
Romain Guy5d4bae72016-11-08 09:49:25 -0800177 return lhs;
Mathias Agopian595ea772013-08-21 23:10:41 -0700178 }
179
180 /*
181 * NOTE: the functions below ARE NOT member methods. They are friend functions
182 * with they definition inlined with their declaration. This makes these
183 * template functions available to the compiler when (and only when) this class
184 * is instantiated, at which point they're only templated on the 2nd parameter
185 * (the first one, BASE<T> being known).
186 */
187
Romain Guy5d4bae72016-11-08 09:49:25 -0800188 /* The operators below handle operation between vectors of the same size
Mathias Agopian595ea772013-08-21 23:10:41 -0700189 * but of a different element type.
190 */
191 template<typename RT>
Romain Guy5d4bae72016-11-08 09:49:25 -0800192 friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<RT>& rv) {
193 // don't pass lv by reference because we need a copy anyways
194 return lv *= rv;
Mathias Agopian595ea772013-08-21 23:10:41 -0700195 }
196 template<typename RT>
Romain Guy5d4bae72016-11-08 09:49:25 -0800197 friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<RT>& rv) {
198 // don't pass lv by reference because we need a copy anyways
199 return lv /= rv;
Mathias Agopian595ea772013-08-21 23:10:41 -0700200 }
201
202 /* The operators below (which are not templates once this class is instanced,
203 * i.e.: BASE<T> is known) can be used for implicit conversion on both sides.
204 * These handle operations like "vector * scalar" and "scalar * vector" by
205 * letting the compiler implicitly convert a scalar to a vector (assuming
206 * the BASE<T> allows it).
207 */
Romain Guy5d4bae72016-11-08 09:49:25 -0800208 friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<T>& rv) {
209 // don't pass lv by reference because we need a copy anyways
210 return lv *= rv;
Mathias Agopian595ea772013-08-21 23:10:41 -0700211 }
Romain Guy5d4bae72016-11-08 09:49:25 -0800212 friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<T>& rv) {
213 // don't pass lv by reference because we need a copy anyways
214 return lv /= rv;
Mathias Agopian595ea772013-08-21 23:10:41 -0700215 }
216};
217
218/*
219 * TVecUnaryOperators implements unary operators on a vector of type BASE<T>.
220 *
221 * BASE only needs to implement operator[] and size().
222 * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically
223 * get all the functionality here.
224 *
225 * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T>
226 */
Romain Guy5d4bae72016-11-08 09:49:25 -0800227template<template<typename T> class VECTOR, typename T>
Mathias Agopian595ea772013-08-21 23:10:41 -0700228class TVecUnaryOperators {
229public:
Romain Guy5d4bae72016-11-08 09:49:25 -0800230 VECTOR<T>& operator ++() {
231 VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
232 for (size_t i = 0; i < rhs.size(); i++) {
Mathias Agopian595ea772013-08-21 23:10:41 -0700233 ++rhs[i];
234 }
235 return rhs;
236 }
Romain Guycaf2ca42016-11-10 11:45:58 -0800237
Romain Guy5d4bae72016-11-08 09:49:25 -0800238 VECTOR<T>& operator --() {
239 VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this);
240 for (size_t i = 0; i < rhs.size(); i++) {
Mathias Agopian595ea772013-08-21 23:10:41 -0700241 --rhs[i];
242 }
243 return rhs;
244 }
Romain Guycaf2ca42016-11-10 11:45:58 -0800245
246 CONSTEXPR VECTOR<T> operator -() const {
Romain Guy5d4bae72016-11-08 09:49:25 -0800247 VECTOR<T> r(VECTOR<T>::NO_INIT);
248 VECTOR<T> const& rv(static_cast<VECTOR<T> const&>(*this));
249 for (size_t i = 0; i < r.size(); i++) {
Mathias Agopian595ea772013-08-21 23:10:41 -0700250 r[i] = -rv[i];
251 }
252 return r;
253 }
254};
255
Mathias Agopian595ea772013-08-21 23:10:41 -0700256/*
257 * TVecComparisonOperators implements relational/comparison operators
258 * on a vector of type BASE<T>.
259 *
260 * BASE only needs to implement operator[] and size().
261 * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically
262 * get all the functionality here.
263 */
Romain Guy5d4bae72016-11-08 09:49:25 -0800264template<template<typename T> class VECTOR, typename T>
Mathias Agopian595ea772013-08-21 23:10:41 -0700265class TVecComparisonOperators {
266public:
267 /*
268 * NOTE: the functions below ARE NOT member methods. They are friend functions
269 * with they definition inlined with their declaration. This makes these
270 * template functions available to the compiler when (and only when) this class
271 * is instantiated, at which point they're only templated on the 2nd parameter
272 * (the first one, BASE<T> being known).
273 */
274 template<typename RT>
275 friend inline
Romain Guy5d4bae72016-11-08 09:49:25 -0800276 bool PURE operator ==(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
277 for (size_t i = 0; i < lv.size(); i++)
Mathias Agopian595ea772013-08-21 23:10:41 -0700278 if (lv[i] != rv[i])
279 return false;
280 return true;
281 }
282
283 template<typename RT>
284 friend inline
Romain Guy5d4bae72016-11-08 09:49:25 -0800285 bool PURE operator !=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Mathias Agopian595ea772013-08-21 23:10:41 -0700286 return !operator ==(lv, rv);
287 }
288
289 template<typename RT>
290 friend inline
Romain Guy5d4bae72016-11-08 09:49:25 -0800291 bool PURE operator >(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
292 for (size_t i = 0; i < lv.size(); i++) {
293 if (lv[i] == rv[i]) {
294 continue;
295 }
296 return lv[i] > rv[i];
297 }
298 return false;
Mathias Agopian595ea772013-08-21 23:10:41 -0700299 }
300
301 template<typename RT>
302 friend inline
Romain Guy5d4bae72016-11-08 09:49:25 -0800303 constexpr bool PURE operator <=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Mathias Agopian595ea772013-08-21 23:10:41 -0700304 return !(lv > rv);
305 }
306
307 template<typename RT>
308 friend inline
Romain Guy5d4bae72016-11-08 09:49:25 -0800309 bool PURE operator <(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
310 for (size_t i = 0; i < lv.size(); i++) {
311 if (lv[i] == rv[i]) {
312 continue;
313 }
314 return lv[i] < rv[i];
315 }
316 return false;
Mathias Agopian595ea772013-08-21 23:10:41 -0700317 }
318
319 template<typename RT>
320 friend inline
Romain Guy5d4bae72016-11-08 09:49:25 -0800321 constexpr bool PURE operator >=(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Mathias Agopian595ea772013-08-21 23:10:41 -0700322 return !(lv < rv);
323 }
Romain Guy11ecb632017-01-27 20:04:01 -0800324
325 template<typename RT>
326 friend inline
Romain Guyeedb69a2017-01-30 17:31:58 -0800327 CONSTEXPR VECTOR<bool> PURE equal(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Romain Guy11ecb632017-01-27 20:04:01 -0800328 VECTOR<bool> r;
329 for (size_t i = 0; i < lv.size(); i++) {
330 r[i] = lv[i] == rv[i];
331 }
332 return r;
333 }
334
335 template<typename RT>
336 friend inline
Romain Guyeedb69a2017-01-30 17:31:58 -0800337 CONSTEXPR VECTOR<bool> PURE notEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Romain Guy11ecb632017-01-27 20:04:01 -0800338 VECTOR<bool> r;
339 for (size_t i = 0; i < lv.size(); i++) {
340 r[i] = lv[i] != rv[i];
341 }
342 return r;
343 }
344
345 template<typename RT>
346 friend inline
Romain Guyeedb69a2017-01-30 17:31:58 -0800347 CONSTEXPR VECTOR<bool> PURE lessThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Romain Guy11ecb632017-01-27 20:04:01 -0800348 VECTOR<bool> r;
349 for (size_t i = 0; i < lv.size(); i++) {
350 r[i] = lv[i] < rv[i];
351 }
352 return r;
353 }
354
355 template<typename RT>
356 friend inline
Romain Guyeedb69a2017-01-30 17:31:58 -0800357 CONSTEXPR VECTOR<bool> PURE lessThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Romain Guy11ecb632017-01-27 20:04:01 -0800358 VECTOR<bool> r;
359 for (size_t i = 0; i < lv.size(); i++) {
360 r[i] = lv[i] <= rv[i];
361 }
362 return r;
363 }
364
365 template<typename RT>
366 friend inline
Romain Guyeedb69a2017-01-30 17:31:58 -0800367 CONSTEXPR VECTOR<bool> PURE greaterThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Romain Guy11ecb632017-01-27 20:04:01 -0800368 VECTOR<bool> r;
369 for (size_t i = 0; i < lv.size(); i++) {
370 r[i] = lv[i] > rv[i];
371 }
372 return r;
373 }
374
375 template<typename RT>
376 friend inline
Romain Guyeedb69a2017-01-30 17:31:58 -0800377 CONSTEXPR VECTOR<bool> PURE greaterThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Romain Guy11ecb632017-01-27 20:04:01 -0800378 VECTOR<bool> r;
379 for (size_t i = 0; i < lv.size(); i++) {
380 r[i] = lv[i] >= rv[i];
381 }
382 return r;
383 }
Mathias Agopian595ea772013-08-21 23:10:41 -0700384};
385
Mathias Agopian595ea772013-08-21 23:10:41 -0700386/*
387 * TVecFunctions implements functions on a vector of type BASE<T>.
388 *
389 * BASE only needs to implement operator[] and size().
390 * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically
391 * get all the functionality here.
392 */
Romain Guy5d4bae72016-11-08 09:49:25 -0800393template<template<typename T> class VECTOR, typename T>
Mathias Agopian595ea772013-08-21 23:10:41 -0700394class TVecFunctions {
395public:
396 /*
397 * NOTE: the functions below ARE NOT member methods. They are friend functions
398 * with they definition inlined with their declaration. This makes these
399 * template functions available to the compiler when (and only when) this class
400 * is instantiated, at which point they're only templated on the 2nd parameter
401 * (the first one, BASE<T> being known).
402 */
403 template<typename RT>
Romain Guycaf2ca42016-11-10 11:45:58 -0800404 friend inline CONSTEXPR T PURE dot(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Mathias Agopian595ea772013-08-21 23:10:41 -0700405 T r(0);
Romain Guy5d4bae72016-11-08 09:49:25 -0800406 for (size_t i = 0; i < lv.size(); i++) {
407 //r = std::fma(lv[i], rv[i], r);
408 r += lv[i] * rv[i];
409 }
Mathias Agopian595ea772013-08-21 23:10:41 -0700410 return r;
411 }
412
Romain Guy5d4bae72016-11-08 09:49:25 -0800413 friend inline constexpr T PURE norm(const VECTOR<T>& lv) {
414 return std::sqrt(dot(lv, lv));
415 }
416
417 friend inline constexpr T PURE length(const VECTOR<T>& lv) {
418 return norm(lv);
419 }
420
421 friend inline constexpr T PURE norm2(const VECTOR<T>& lv) {
422 return dot(lv, lv);
423 }
424
425 friend inline constexpr T PURE length2(const VECTOR<T>& lv) {
426 return norm2(lv);
Mathias Agopian595ea772013-08-21 23:10:41 -0700427 }
428
429 template<typename RT>
Romain Guy5d4bae72016-11-08 09:49:25 -0800430 friend inline constexpr T PURE distance(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
Mathias Agopian595ea772013-08-21 23:10:41 -0700431 return length(rv - lv);
432 }
433
Romain Guy5d4bae72016-11-08 09:49:25 -0800434 template<typename RT>
435 friend inline constexpr T PURE distance2(const VECTOR<T>& lv, const VECTOR<RT>& rv) {
436 return length2(rv - lv);
437 }
438
439 friend inline constexpr VECTOR<T> PURE normalize(const VECTOR<T>& lv) {
440 return lv * (T(1) / length(lv));
441 }
442
Romain Guycaf2ca42016-11-10 11:45:58 -0800443 friend inline constexpr VECTOR<T> PURE rcp(VECTOR<T> v) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800444 return T(1) / v;
445 }
446
Romain Guycaf2ca42016-11-10 11:45:58 -0800447 friend inline CONSTEXPR VECTOR<T> PURE abs(VECTOR<T> v) {
Romain Guy11ecb632017-01-27 20:04:01 -0800448 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800449 v[i] = std::abs(v[i]);
450 }
451 return v;
452 }
453
Romain Guycaf2ca42016-11-10 11:45:58 -0800454 friend inline CONSTEXPR VECTOR<T> PURE floor(VECTOR<T> v) {
Romain Guy11ecb632017-01-27 20:04:01 -0800455 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800456 v[i] = std::floor(v[i]);
457 }
458 return v;
459 }
460
Romain Guycaf2ca42016-11-10 11:45:58 -0800461 friend inline CONSTEXPR VECTOR<T> PURE ceil(VECTOR<T> v) {
Romain Guy11ecb632017-01-27 20:04:01 -0800462 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800463 v[i] = std::ceil(v[i]);
464 }
465 return v;
466 }
467
Romain Guycaf2ca42016-11-10 11:45:58 -0800468 friend inline CONSTEXPR VECTOR<T> PURE round(VECTOR<T> v) {
Romain Guy11ecb632017-01-27 20:04:01 -0800469 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800470 v[i] = std::round(v[i]);
471 }
472 return v;
473 }
474
Romain Guycaf2ca42016-11-10 11:45:58 -0800475 friend inline CONSTEXPR VECTOR<T> PURE inversesqrt(VECTOR<T> v) {
Romain Guy11ecb632017-01-27 20:04:01 -0800476 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800477 v[i] = T(1) / std::sqrt(v[i]);
478 }
479 return v;
480 }
481
Romain Guycaf2ca42016-11-10 11:45:58 -0800482 friend inline CONSTEXPR VECTOR<T> PURE sqrt(VECTOR<T> v) {
Romain Guy11ecb632017-01-27 20:04:01 -0800483 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800484 v[i] = std::sqrt(v[i]);
485 }
486 return v;
487 }
488
Romain Guycaf2ca42016-11-10 11:45:58 -0800489 friend inline CONSTEXPR VECTOR<T> PURE pow(VECTOR<T> v, T p) {
Romain Guy11ecb632017-01-27 20:04:01 -0800490 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800491 v[i] = std::pow(v[i], p);
492 }
493 return v;
494 }
495
Romain Guycaf2ca42016-11-10 11:45:58 -0800496 friend inline CONSTEXPR VECTOR<T> PURE saturate(const VECTOR<T>& lv) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800497 return clamp(lv, T(0), T(1));
498 }
499
Romain Guycaf2ca42016-11-10 11:45:58 -0800500 friend inline CONSTEXPR VECTOR<T> PURE clamp(VECTOR<T> v, T min, T max) {
Romain Guy11ecb632017-01-27 20:04:01 -0800501 for (size_t i = 0; i< v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800502 v[i] = std::min(max, std::max(min, v[i]));
503 }
504 return v;
505 }
506
Romain Guycaf2ca42016-11-10 11:45:58 -0800507 friend inline CONSTEXPR VECTOR<T> PURE fma(const VECTOR<T>& lv, const VECTOR<T>& rv, VECTOR<T> a) {
Romain Guy11ecb632017-01-27 20:04:01 -0800508 for (size_t i = 0; i<lv.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800509 //a[i] = std::fma(lv[i], rv[i], a[i]);
510 a[i] += (lv[i] * rv[i]);
511 }
512 return a;
513 }
514
Romain Guycaf2ca42016-11-10 11:45:58 -0800515 friend inline CONSTEXPR VECTOR<T> PURE min(const VECTOR<T>& u, VECTOR<T> v) {
Romain Guy11ecb632017-01-27 20:04:01 -0800516 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800517 v[i] = std::min(u[i], v[i]);
518 }
519 return v;
520 }
521
Romain Guycaf2ca42016-11-10 11:45:58 -0800522 friend inline CONSTEXPR VECTOR<T> PURE max(const VECTOR<T>& u, VECTOR<T> v) {
Romain Guy11ecb632017-01-27 20:04:01 -0800523 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800524 v[i] = std::max(u[i], v[i]);
525 }
526 return v;
527 }
528
Romain Guycaf2ca42016-11-10 11:45:58 -0800529 friend inline CONSTEXPR T PURE max(const VECTOR<T>& v) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800530 T r(std::numeric_limits<T>::lowest());
Romain Guy11ecb632017-01-27 20:04:01 -0800531 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800532 r = std::max(r, v[i]);
533 }
534 return r;
535 }
536
Romain Guycaf2ca42016-11-10 11:45:58 -0800537 friend inline CONSTEXPR T PURE min(const VECTOR<T>& v) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800538 T r(std::numeric_limits<T>::max());
Romain Guy11ecb632017-01-27 20:04:01 -0800539 for (size_t i = 0; i < v.size(); i++) {
Romain Guy5d4bae72016-11-08 09:49:25 -0800540 r = std::min(r, v[i]);
541 }
542 return r;
543 }
Romain Guycaf2ca42016-11-10 11:45:58 -0800544
545 friend inline CONSTEXPR VECTOR<T> PURE apply(VECTOR<T> v, const std::function<T(T)>& f) {
Romain Guy11ecb632017-01-27 20:04:01 -0800546 for (size_t i = 0; i < v.size(); i++) {
Romain Guycaf2ca42016-11-10 11:45:58 -0800547 v[i] = f(v[i]);
548 }
549 return v;
550 }
Romain Guy11ecb632017-01-27 20:04:01 -0800551
552 friend inline CONSTEXPR bool PURE any(const VECTOR<T>& v) {
553 for (size_t i = 0; i < v.size(); i++) {
554 if (v[i] != T(0)) return true;
555 }
556 return false;
557 }
558
559 friend inline CONSTEXPR bool PURE all(const VECTOR<T>& v) {
560 bool result = true;
561 for (size_t i = 0; i < v.size(); i++) {
562 result &= (v[i] != T(0));
563 }
564 return result;
565 }
566
567 template<typename R>
568 friend inline CONSTEXPR VECTOR<R> PURE map(VECTOR<T> v, const std::function<R(T)>& f) {
569 VECTOR<R> result;
570 for (size_t i = 0; i < v.size(); i++) {
571 result[i] = f(v[i]);
572 }
573 return result;
574 }
Romain Guy5d4bae72016-11-08 09:49:25 -0800575};
576
577/*
578 * TVecDebug implements functions on a vector of type BASE<T>.
579 *
580 * BASE only needs to implement operator[] and size().
581 * By simply inheriting from TVecDebug<BASE, T> BASE will automatically
582 * get all the functionality here.
583 */
584template<template<typename T> class VECTOR, typename T>
585class TVecDebug {
586public:
587 /*
588 * NOTE: the functions below ARE NOT member methods. They are friend functions
589 * with they definition inlined with their declaration. This makes these
590 * template functions available to the compiler when (and only when) this class
591 * is instantiated, at which point they're only templated on the 2nd parameter
592 * (the first one, BASE<T> being known).
593 */
594 friend std::ostream& operator<<(std::ostream& stream, const VECTOR<T>& v) {
595 stream << "< ";
596 for (size_t i = 0; i < v.size() - 1; i++) {
597 stream << T(v[i]) << ", ";
598 }
599 stream << T(v[v.size() - 1]) << " >";
600 return stream;
Mathias Agopian595ea772013-08-21 23:10:41 -0700601 }
602};
603
Romain Guycaf2ca42016-11-10 11:45:58 -0800604#undef CONSTEXPR
Mathias Agopian595ea772013-08-21 23:10:41 -0700605#undef PURE
606
607// -------------------------------------------------------------------------------------
Romain Guy5d4bae72016-11-08 09:49:25 -0800608} // namespace details
609} // namespace android
Mathias Agopian595ea772013-08-21 23:10:41 -0700610
611
Romain Guy5d4bae72016-11-08 09:49:25 -0800612#endif // UI_TVECHELPERS_H_