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 181d77b719d51a01cbd6954a048fb64e79d50a950eMathias Agopian#pragma once 19595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <math.h> 21595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#include <stdint.h> 22595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#include <sys/types.h> 23595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <cmath> 255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <limits> 265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy#include <iostream> 275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 28595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#define PURE __attribute__((pure)) 29595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 30caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#if __cplusplus >= 201402L 31caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#define CONSTEXPR constexpr 32caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#else 33caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#define CONSTEXPR 34caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#endif 35caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy 36595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopiannamespace android { 375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guynamespace details { 38595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian// ------------------------------------------------------------------------------------- 39595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 40595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/* 41595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * No user serviceable parts here. 42595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 43595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * Don't use this file directly, instead include ui/vec{2|3|4}.h 44595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 45595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 46595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/* 471d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * TVec{Add|Product}Operators implements basic arithmetic and basic compound assignments 48595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * operators on a vector of type BASE<T>. 49595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 50595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * BASE only needs to implement operator[] and size(). 511d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * By simply inheriting from TVec{Add|Product}Operators<BASE, T> BASE will automatically 52595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * get all the functionality here. 53595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 54595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate <template<typename T> class VECTOR, typename T> 561d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianclass TVecAddOperators { 57595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianpublic: 58595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian /* compound assignment from a another vector of the same size but different 59595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * element type. 60595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 615d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename OTHER> 625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator +=(const VECTOR<OTHER>& v) { 635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lhs.size(); i++) { 655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy lhs[i] += v[i]; 66595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lhs; 68595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename OTHER> 705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator -=(const VECTOR<OTHER>& v) { 715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lhs.size(); i++) { 735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy lhs[i] -= v[i]; 74595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lhs; 76595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 771d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 781d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian /* compound assignment from a another vector of the same type. 791d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * These operators can be used for implicit conversion and handle operations 801d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * like "vector *= scalar" by letting the compiler implicitly convert a scalar 811d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * to a vector (assuming the BASE<T> allows it). 821d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian */ 835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator +=(const VECTOR<T>& v) { 845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 855d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lhs.size(); i++) { 865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy lhs[i] += v[i]; 87595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lhs; 89595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator -=(const VECTOR<T>& v) { 915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lhs.size(); i++) { 935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy lhs[i] -= v[i]; 94595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lhs; 96595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 97595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 981d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian /* 991d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * NOTE: the functions below ARE NOT member methods. They are friend functions 1001d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * with they definition inlined with their declaration. This makes these 1011d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * template functions available to the compiler when (and only when) this class 1021d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * is instantiated, at which point they're only templated on the 2nd parameter 1031d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * (the first one, BASE<T> being known). 104595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 1051d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 1065d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /* The operators below handle operation between vectors of the same size 1071d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * but of a different element type. 1081d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian */ 1091d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian template<typename RT> 1105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<RT>& rv) { 1115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // don't pass lv by reference because we need a copy anyways 1125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv += rv; 1131d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 1141d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian template<typename RT> 1155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<RT>& rv) { 1165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // don't pass lv by reference because we need a copy anyways 1175d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv -= rv; 1181d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 1191d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 1201d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian /* The operators below (which are not templates once this class is instanced, 1211d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * i.e.: BASE<T> is known) can be used for implicit conversion on both sides. 1225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * These handle operations like "vector + scalar" and "scalar + vector" by 1231d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * letting the compiler implicitly convert a scalar to a vector (assuming 1241d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * the BASE<T> allows it). 1251d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian */ 1265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr VECTOR<T> PURE operator +(VECTOR<T> lv, const VECTOR<T>& rv) { 1275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // don't pass lv by reference because we need a copy anyways 1285d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv += rv; 1291d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 1305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr VECTOR<T> PURE operator -(VECTOR<T> lv, const VECTOR<T>& rv) { 1315d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // don't pass lv by reference because we need a copy anyways 1325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv -= rv; 1331d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian } 1341d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian}; 1351d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 1365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<template<typename T> class VECTOR, typename T> 1371d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianclass TVecProductOperators { 1381d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopianpublic: 1391d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian /* compound assignment from a another vector of the same size but different 1401d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * element type. 1411d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian */ 1425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename OTHER> 1435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator *=(const VECTOR<OTHER>& v) { 1445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 1455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lhs.size(); i++) { 1465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy lhs[i] *= v[i]; 147595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 1485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lhs; 149595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 1505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename OTHER> 1515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator /=(const VECTOR<OTHER>& v) { 1525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 1535d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lhs.size(); i++) { 1545d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy lhs[i] /= v[i]; 155595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 1565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lhs; 157595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 1581d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian 1591d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian /* compound assignment from a another vector of the same type. 1601d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * These operators can be used for implicit conversion and handle operations 1611d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * like "vector *= scalar" by letting the compiler implicitly convert a scalar 1621d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian * to a vector (assuming the BASE<T> allows it). 1631d4d8f94e2989b7c8667602304df9059d2701653Mathias Agopian */ 1645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator *=(const VECTOR<T>& v) { 1655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 1665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lhs.size(); i++) { 1675d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy lhs[i] *= v[i]; 168595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 1695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lhs; 170595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 1715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator /=(const VECTOR<T>& v) { 1725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& lhs = static_cast<VECTOR<T>&>(*this); 1735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lhs.size(); i++) { 1745d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy lhs[i] /= v[i]; 175595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 1765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lhs; 177595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 178595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 179595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian /* 180595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * NOTE: the functions below ARE NOT member methods. They are friend functions 181595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * with they definition inlined with their declaration. This makes these 182595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * template functions available to the compiler when (and only when) this class 183595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * is instantiated, at which point they're only templated on the 2nd parameter 184595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * (the first one, BASE<T> being known). 185595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 186595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 1875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /* The operators below handle operation between vectors of the same size 188595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * but of a different element type. 189595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 190595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 1915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<RT>& rv) { 1925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // don't pass lv by reference because we need a copy anyways 1935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv *= rv; 194595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 195595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 1965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<RT>& rv) { 1975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // don't pass lv by reference because we need a copy anyways 1985d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv /= rv; 199595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 200595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 201595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian /* The operators below (which are not templates once this class is instanced, 202595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * i.e.: BASE<T> is known) can be used for implicit conversion on both sides. 203595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * These handle operations like "vector * scalar" and "scalar * vector" by 204595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * letting the compiler implicitly convert a scalar to a vector (assuming 205595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * the BASE<T> allows it). 206595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 2075d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr VECTOR<T> PURE operator *(VECTOR<T> lv, const VECTOR<T>& rv) { 2085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // don't pass lv by reference because we need a copy anyways 2095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv *= rv; 210595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 2115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr VECTOR<T> PURE operator /(VECTOR<T> lv, const VECTOR<T>& rv) { 2125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy // don't pass lv by reference because we need a copy anyways 2135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv /= rv; 214595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 215595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian}; 216595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 217595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/* 218595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * TVecUnaryOperators implements unary operators on a vector of type BASE<T>. 219595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 220595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * BASE only needs to implement operator[] and size(). 221595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * By simply inheriting from TVecUnaryOperators<BASE, T> BASE will automatically 222595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * get all the functionality here. 223595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 224595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * These operators are implemented as friend functions of TVecUnaryOperators<BASE, T> 225595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 2265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<template<typename T> class VECTOR, typename T> 227595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianclass TVecUnaryOperators { 228595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianpublic: 2295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator ++() { 2305d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this); 2315d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < rhs.size(); i++) { 232595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian ++rhs[i]; 233595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 234595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return rhs; 235595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 236caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy 2375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& operator --() { 2385d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T>& rhs = static_cast<VECTOR<T>&>(*this); 2395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < rhs.size(); i++) { 240595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian --rhs[i]; 241595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 242595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return rhs; 243595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 244caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy 245caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy CONSTEXPR VECTOR<T> operator -() const { 2465d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T> r(VECTOR<T>::NO_INIT); 2475d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy VECTOR<T> const& rv(static_cast<VECTOR<T> const&>(*this)); 2485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < r.size(); i++) { 249595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian r[i] = -rv[i]; 250595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 251595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return r; 252595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 253595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian}; 254595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 255595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/* 256595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * TVecComparisonOperators implements relational/comparison operators 257595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * on a vector of type BASE<T>. 258595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 259595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * BASE only needs to implement operator[] and size(). 260595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * By simply inheriting from TVecComparisonOperators<BASE, T> BASE will automatically 261595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * get all the functionality here. 262595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 2635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<template<typename T> class VECTOR, typename T> 264595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianclass TVecComparisonOperators { 265595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianpublic: 266595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian /* 267595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * NOTE: the functions below ARE NOT member methods. They are friend functions 268595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * with they definition inlined with their declaration. This makes these 269595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * template functions available to the compiler when (and only when) this class 270595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * is instantiated, at which point they're only templated on the 2nd parameter 271595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * (the first one, BASE<T> being known). 272595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 273595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 274595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian friend inline 2755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy bool PURE operator ==(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 2765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lv.size(); i++) 277595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian if (lv[i] != rv[i]) 278595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return false; 279595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return true; 280595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 281595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 282595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 283595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian friend inline 2845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy bool PURE operator !=(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 285595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return !operator ==(lv, rv); 286595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 287595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 288595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 289595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian friend inline 2905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy bool PURE operator >(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 2915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lv.size(); i++) { 2925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy if (lv[i] == rv[i]) { 2935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy continue; 2945d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 2955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv[i] > rv[i]; 2965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 2975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return false; 298595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 299595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 300595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 301595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian friend inline 3025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr bool PURE operator <=(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 303595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return !(lv > rv); 304595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 305595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 306595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 307595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian friend inline 3085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy bool PURE operator <(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 3095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lv.size(); i++) { 3105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy if (lv[i] == rv[i]) { 3115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy continue; 3125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 3135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv[i] < rv[i]; 3145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 3155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return false; 316595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 317595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 318595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 319595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian friend inline 3205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy constexpr bool PURE operator >=(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 321595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return !(lv < rv); 322595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 32311ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy 32411ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy template<typename RT> 32511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy friend inline 326eedb69abbde29ad3dd624f1f9dfc72e4f35d5234Romain Guy CONSTEXPR VECTOR<bool> PURE equal(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 32711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy VECTOR<bool> r; 32811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < lv.size(); i++) { 32911ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy r[i] = lv[i] == rv[i]; 33011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 33111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy return r; 33211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 33311ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy 33411ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy template<typename RT> 33511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy friend inline 336eedb69abbde29ad3dd624f1f9dfc72e4f35d5234Romain Guy CONSTEXPR VECTOR<bool> PURE notEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 33711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy VECTOR<bool> r; 33811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < lv.size(); i++) { 33911ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy r[i] = lv[i] != rv[i]; 34011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 34111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy return r; 34211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 34311ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy 34411ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy template<typename RT> 34511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy friend inline 346eedb69abbde29ad3dd624f1f9dfc72e4f35d5234Romain Guy CONSTEXPR VECTOR<bool> PURE lessThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 34711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy VECTOR<bool> r; 34811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < lv.size(); i++) { 34911ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy r[i] = lv[i] < rv[i]; 35011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 35111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy return r; 35211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 35311ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy 35411ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy template<typename RT> 35511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy friend inline 356eedb69abbde29ad3dd624f1f9dfc72e4f35d5234Romain Guy CONSTEXPR VECTOR<bool> PURE lessThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 35711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy VECTOR<bool> r; 35811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < lv.size(); i++) { 35911ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy r[i] = lv[i] <= rv[i]; 36011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 36111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy return r; 36211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 36311ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy 36411ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy template<typename RT> 36511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy friend inline 366eedb69abbde29ad3dd624f1f9dfc72e4f35d5234Romain Guy CONSTEXPR VECTOR<bool> PURE greaterThan(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 36711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy VECTOR<bool> r; 36811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < lv.size(); i++) { 36911ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy r[i] = lv[i] > rv[i]; 37011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 37111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy return r; 37211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 37311ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy 37411ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy template<typename RT> 37511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy friend inline 376eedb69abbde29ad3dd624f1f9dfc72e4f35d5234Romain Guy CONSTEXPR VECTOR<bool> PURE greaterThanEqual(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 37711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy VECTOR<bool> r; 37811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < lv.size(); i++) { 37911ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy r[i] = lv[i] >= rv[i]; 38011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 38111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy return r; 38211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 383595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian}; 384595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 385595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian/* 386595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * TVecFunctions implements functions on a vector of type BASE<T>. 387595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * 388595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * BASE only needs to implement operator[] and size(). 389595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * By simply inheriting from TVecFunctions<BASE, T> BASE will automatically 390595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * get all the functionality here. 391595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 3925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<template<typename T> class VECTOR, typename T> 393595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianclass TVecFunctions { 394595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopianpublic: 395595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian /* 396595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * NOTE: the functions below ARE NOT member methods. They are friend functions 397595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * with they definition inlined with their declaration. This makes these 398595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * template functions available to the compiler when (and only when) this class 399595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * is instantiated, at which point they're only templated on the 2nd parameter 400595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian * (the first one, BASE<T> being known). 401595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian */ 402595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 403caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR T PURE dot(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 404595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian T r(0); 4055d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < lv.size(); i++) { 4065d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy //r = std::fma(lv[i], rv[i], r); 4075d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy r += lv[i] * rv[i]; 4085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 409595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return r; 410595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 411595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 4125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr T PURE norm(const VECTOR<T>& lv) { 4135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return std::sqrt(dot(lv, lv)); 4145d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4155d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 4165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr T PURE length(const VECTOR<T>& lv) { 4175d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return norm(lv); 4185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 4205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr T PURE norm2(const VECTOR<T>& lv) { 4215d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return dot(lv, lv); 4225d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 4245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr T PURE length2(const VECTOR<T>& lv) { 4255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return norm2(lv); 426595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 427595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 428595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian template<typename RT> 4295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr T PURE distance(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 430595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian return length(rv - lv); 431595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 432595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 4335d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy template<typename RT> 4345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr T PURE distance2(const VECTOR<T>& lv, const VECTOR<RT>& rv) { 4355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return length2(rv - lv); 4365d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 4385d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend inline constexpr VECTOR<T> PURE normalize(const VECTOR<T>& lv) { 4395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return lv * (T(1) / length(lv)); 4405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 442caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline constexpr VECTOR<T> PURE rcp(VECTOR<T> v) { 4435d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return T(1) / v; 4445d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4455d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 446caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE abs(VECTOR<T> v) { 44711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 4485d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = std::abs(v[i]); 4495d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4505d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 4515d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4525d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 453caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE floor(VECTOR<T> v) { 45411ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 4555d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = std::floor(v[i]); 4565d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4575d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 4585d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4595d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 460caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE ceil(VECTOR<T> v) { 46111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 4625d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = std::ceil(v[i]); 4635d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4645d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 4655d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4665d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 467caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE round(VECTOR<T> v) { 46811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 4695d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = std::round(v[i]); 4705d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4715d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 4725d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4735d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 474caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE inversesqrt(VECTOR<T> v) { 47511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 4765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = T(1) / std::sqrt(v[i]); 4775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 4795d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4805d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 481caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE sqrt(VECTOR<T> v) { 48211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 4835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = std::sqrt(v[i]); 4845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4855d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 4865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 488caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE pow(VECTOR<T> v, T p) { 48911ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 4905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = std::pow(v[i], p); 4915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 4935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4945d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 495caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE saturate(const VECTOR<T>& lv) { 4965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return clamp(lv, T(0), T(1)); 4975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 4985d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 499caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE clamp(VECTOR<T> v, T min, T max) { 50011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i< v.size(); i++) { 5015d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = std::min(max, std::max(min, v[i])); 5025d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5035d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 5045d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5055d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 506caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE fma(const VECTOR<T>& lv, const VECTOR<T>& rv, VECTOR<T> a) { 50711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i<lv.size(); i++) { 5085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy //a[i] = std::fma(lv[i], rv[i], a[i]); 5095d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy a[i] += (lv[i] * rv[i]); 5105d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5115d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return a; 5125d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5135d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 514caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE min(const VECTOR<T>& u, VECTOR<T> v) { 51511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 5165d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = std::min(u[i], v[i]); 5175d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5185d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 5195d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5205d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 521caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE max(const VECTOR<T>& u, VECTOR<T> v) { 52211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 5235d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy v[i] = std::max(u[i], v[i]); 5245d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5255d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return v; 5265d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5275d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 528caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR T PURE max(const VECTOR<T>& v) { 5295d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy T r(std::numeric_limits<T>::lowest()); 53011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 5315d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy r = std::max(r, v[i]); 5325d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5335d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return r; 5345d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5355d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 536caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR T PURE min(const VECTOR<T>& v) { 5375d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy T r(std::numeric_limits<T>::max()); 53811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 5395d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy r = std::min(r, v[i]); 5405d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5415d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return r; 5425d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 543caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy 544caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy friend inline CONSTEXPR VECTOR<T> PURE apply(VECTOR<T> v, const std::function<T(T)>& f) { 54511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 546caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy v[i] = f(v[i]); 547caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy } 548caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy return v; 549caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy } 55011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy 55111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy friend inline CONSTEXPR bool PURE any(const VECTOR<T>& v) { 55211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 55311ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy if (v[i] != T(0)) return true; 55411ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 55511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy return false; 55611ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 55711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy 55811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy friend inline CONSTEXPR bool PURE all(const VECTOR<T>& v) { 55911ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy bool result = true; 56011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 56111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy result &= (v[i] != T(0)); 56211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 56311ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy return result; 56411ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 56511ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy 56611ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy template<typename R> 56711ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy friend inline CONSTEXPR VECTOR<R> PURE map(VECTOR<T> v, const std::function<R(T)>& f) { 56811ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy VECTOR<R> result; 56911ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy for (size_t i = 0; i < v.size(); i++) { 57011ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy result[i] = f(v[i]); 57111ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 57211ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy return result; 57311ecb63414d2fea2f4217db8bb06a998bcf8b425Romain Guy } 5745d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy}; 5755d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy 5765d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy/* 5775d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * TVecDebug implements functions on a vector of type BASE<T>. 5785d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * 5795d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * BASE only needs to implement operator[] and size(). 5805d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * By simply inheriting from TVecDebug<BASE, T> BASE will automatically 5815d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * get all the functionality here. 5825d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 5835d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guytemplate<template<typename T> class VECTOR, typename T> 5845d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guyclass TVecDebug { 5855d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guypublic: 5865d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy /* 5875d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * NOTE: the functions below ARE NOT member methods. They are friend functions 5885d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * with they definition inlined with their declaration. This makes these 5895d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * template functions available to the compiler when (and only when) this class 5905d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * is instantiated, at which point they're only templated on the 2nd parameter 5915d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy * (the first one, BASE<T> being known). 5925d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy */ 5935d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy friend std::ostream& operator<<(std::ostream& stream, const VECTOR<T>& v) { 5945d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy stream << "< "; 5955d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy for (size_t i = 0; i < v.size() - 1; i++) { 5965d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy stream << T(v[i]) << ", "; 5975d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy } 5985d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy stream << T(v[v.size() - 1]) << " >"; 5995d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy return stream; 600595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian } 601595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian}; 602595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 603caf2ca414f69d460c516e2370cf42bcf49178d95Romain Guy#undef CONSTEXPR 604595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian#undef PURE 605595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian 606595ea77f6bdb5e9d0ddd3305da7a44b56f326b2cMathias Agopian// ------------------------------------------------------------------------------------- 6075d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace details 6085d4bae7f170640e0e280b3ca8a22b18e80801a8aRomain Guy} // namespace android 609