6#include "TTauri/Foundation/required.hpp"
7#include "TTauri/Foundation/numeric_cast.hpp"
8#include "TTauri/Foundation/type_traits.hpp"
17#if TT_COMPILER == TT_CC_MSVC
20#if TT_PROCESSOR == TT_CPU_X64
26constexpr long double pi = 3.141592653589793238462643383279502884L;
28constexpr long long pow10_table[20] {
43 100'000'000'000'000LL,
44 1'000'000'000'000'000LL,
45 10'000'000'000'000'000LL,
46 100'000'000'000'000'000LL,
47 1'000'000'000'000'000'000LL,
50constexpr long long pow10ll(
int x)
noexcept {
51 tt_assume(x >= 0 && x <= 18);
52 return pow10_table[x];
55template<
typename T, std::enable_if_t<std::is_
integral_v<T> && std::is_
unsigned_v<T>,
int> = 0>
56constexpr int bsr(T x)
noexcept
58#if TT_COMPILER == TT_CC_MSVC
59 if constexpr (
sizeof(T) == 4) {
61 auto found = _BitScanReverse(&index, x);
62 return found ? index : -1;
64 }
else if constexpr (
sizeof(T) == 8) {
66 auto found = _BitScanReverse64(&index, x);
67 return found ? index : -1;
72#elif TT_COMPILER == TT_CC_CLANG || TT_COMPILER == TT_CC_GCC
73 if constexpr (std::is_same_v<T,unsigned int>) {
74 auto tmp = __builtin_clz(x);
75 return x == 0 ? -1 : ssizeof(T) * 8 - tmp - 1;
77 }
else if constexpr (std::is_same_v<T,unsigned long>) {
78 auto tmp = __builtin_clzl(x);
79 return x == 0 ? -1 : ssizeof(T) * 8 - tmp - 1;
81 }
else if constexpr (std::is_same_v<T,unsigned long long>) {
82 auto tmp = __builtin_clzll(x);
83 return x == 0 ? -1 : ssizeof(T) * 8 - tmp - 1;
89#error "Not implemented"
94constexpr auto next_power_of_two(T rhs)
96 make_larger_t<T> x = rhs;
102 if constexpr (
sizeof(T) >= 2) {
105 if constexpr (
sizeof(T) >= 4) {
108 if constexpr (
sizeof(T) >= 8) {
119constexpr T make_mask(T x)
121 ttlet p2 = next_power_of_two(x);
122 return static_cast<T
>(p2 - 1);
129template<
typename T, std::enable_if_t<std::is_
integral_v<T> && std::is_
unsigned_v<T>,
int> = 0>
130constexpr int popcount(T x)
noexcept
132#if TT_COMPILER == TT_CC_MSVC
133 if constexpr (
sizeof(T) ==
sizeof(
unsigned __int64)) {
134 return __popcnt64(x);
135 }
else if constexpr (
sizeof(T) ==
sizeof(
unsigned int)) {
137 }
else if constexpr (
sizeof(T) ==
sizeof(
unsigned short)) {
138 return __popcnt16(x);
140 return __popcnt64(
static_cast<unsigned __int64
>(x));
142#elif TT_COMPILER == TT_CC_CLANG || TT_COMPILER == TT_CC_GCC
143 if constexpr (std::is_same_v<T,unsigned int>) {
144 return __builtin_popcount(x);
146 }
else if constexpr (std::is_same_v<T,unsigned long>) {
147 return __builtin_popcountl(x);
149 }
else if constexpr (std::is_same_v<T,unsigned long long>) {
150 return __builtin_popcountll(x);
156#error "Not implemented"
160template<
typename T, std::enable_if_t<std::is_
integral_v<T> && std::is_
unsigned_v<T>,
int> = 0>
161constexpr T rotl(T x,
unsigned int count)
noexcept
163#if TT_COMPILER == TT_CC_MSVC
164 if constexpr (
sizeof(T) == 1) {
165 return _rotl8(x, count);
166 }
else if constexpr (
sizeof(T) == 2) {
167 return _rotl16(x, count);
168 }
else if constexpr (
sizeof(T) == 4) {
169 return _rotl(x, count);
170 }
else if constexpr (
sizeof(T) == 8) {
171 return _rotl64(x, count);
173 constexpr unsigned int mask = (8 *
sizeof(T)) - 1;
174 return x << count | x >> (-
count & mask);
177 constexpr unsigned int mask = (8 *
sizeof(T)) - 1;
178 return x << count | x >> (-
count & mask);
182template<
typename T, std::enable_if_t<std::is_
integral_v<T> && std::is_
unsigned_v<T>,
int> = 0>
183constexpr T rotr(T x,
unsigned int count)
noexcept
185#if TT_COMPILER == TT_CC_MSVC
186 if constexpr (
sizeof(T) == 1) {
187 return _rotr8(x, count);
188 }
else if constexpr (
sizeof(T) == 2) {
189 return _rotr16(x, count);
190 }
else if constexpr (
sizeof(T) == 4) {
191 return _rotr(x, count);
192 }
else if constexpr (
sizeof(T) == 8) {
193 return _rotr64(x, count);
195 constexpr unsigned int mask = (8 *
sizeof(T)) - 1;
199 constexpr unsigned int mask = (8 *
sizeof(T)) - 1;
205constexpr T median(T a, T b, T c)
noexcept {
209inline bool almost_equal(
float a,
float b)
noexcept {
216 auto a__ =
static_cast<int>(a_ & 0x7ffffff);
217 auto b__ =
static_cast<int>(b_ & 0x7ffffff);
219 if ((a_ < 0) == (b_ < 0)) {
220 return std::abs(a__ - b__) < 10;
222 return std::abs(a__ + b__) < 10;
226template<
typename Iterator>
227auto mean(Iterator first, Iterator last)
231 ttlet sum = std::reduce(first, last, init);
237template<
typename Iterator,
typename T>
238auto stddev(Iterator first, Iterator last, T mean)
242 ttlet sum =
std::accumulate(first, last, init, [=](ttlet &acc, ttlet &value) {
243 ttlet tmp = value - mean;
244 return acc + tmp*tmp;