File indexing completed on 2025-12-03 09:14:57
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <cassert>
0012 #include <cmath>
0013 #include <type_traits>
0014 namespace Acts {
0015
0016
0017
0018
0019
0020 template <typename T>
0021 constexpr T abs(const T n) {
0022 if (std::is_constant_evaluated()) {
0023 if constexpr (std::is_signed_v<T>) {
0024 if (n < 0) {
0025 return -n;
0026 }
0027 }
0028 return n;
0029 } else {
0030 return std::abs(n);
0031 }
0032 }
0033
0034
0035
0036
0037
0038
0039 template <typename out_t, typename sign_t>
0040 constexpr out_t copySign(const out_t& copyTo, const sign_t& sign) {
0041 if constexpr (std::is_enum_v<sign_t>) {
0042 return copySign(copyTo, static_cast<std::underlying_type_t<sign_t>>(sign));
0043 } else {
0044 constexpr sign_t zero = 0;
0045 return sign >= zero ? copyTo : -copyTo;
0046 }
0047 }
0048
0049
0050
0051
0052
0053 template <typename T, std::integral P>
0054 constexpr T pow(T x, P p) {
0055 if (std::is_constant_evaluated()) {
0056 constexpr T one = 1;
0057 if constexpr (std::is_signed_v<P>) {
0058 if (p < 0 && abs(x) > std::numeric_limits<T>::epsilon()) {
0059 x = one / x;
0060 p = -p;
0061 }
0062 }
0063 using unsigned_p = std::make_unsigned_t<P>;
0064 return p == 0 ? one : x * pow(x, static_cast<unsigned_p>(p) - 1);
0065 } else {
0066 return static_cast<T>(std::pow(x, static_cast<T>(p)));
0067 }
0068 }
0069
0070
0071
0072
0073 template <typename T>
0074 constexpr auto square(T x) {
0075 return x * x;
0076 }
0077
0078
0079
0080
0081 template <typename... T>
0082 constexpr auto hypotSquare(T... args) {
0083 return (square(args) + ...);
0084 }
0085
0086
0087
0088
0089 template <typename... T>
0090 constexpr auto fastHypot(T... args) {
0091 return std::sqrt(hypotSquare(args...));
0092 }
0093
0094
0095
0096
0097
0098 template <std::integral T>
0099 constexpr T sumUpToN(const T N) {
0100 return N * (N + 1) / 2;
0101 }
0102
0103
0104
0105
0106
0107 template <std::integral T>
0108 constexpr T factorial(const T upperN, const T lowerN = 1) {
0109 constexpr T one = 1;
0110 const T& limit = std::max(one, lowerN);
0111 return upperN >= limit ? upperN * factorial(upperN - 1, limit) : one;
0112 }
0113
0114
0115
0116
0117
0118
0119
0120 template <std::integral T>
0121 constexpr T binomial(const T n, const T k) {
0122 return factorial<T>(n, n - k + 1) / factorial<T>(k);
0123 }
0124
0125 }