1#pragma once
2
3#include <cmath>
4#include <limits>
5#include <type_traits>
6
7
8/// To be sure, that this function is zero-cost for non-floating point types.
9template <typename T>
10inline std::enable_if_t<std::is_floating_point_v<T>, bool> isNaN(T x)
11{
12 return std::isnan(x);
13}
14
15template <typename T>
16inline std::enable_if_t<!std::is_floating_point_v<T>, bool> isNaN(T)
17{
18 return false;
19}
20
21template <typename T>
22inline std::enable_if_t<std::is_floating_point_v<T>, bool> isFinite(T x)
23{
24 return std::isfinite(x);
25}
26
27template <typename T>
28inline std::enable_if_t<!std::is_floating_point_v<T>, bool> isFinite(T)
29{
30 return true;
31}
32
33template <typename T>
34std::enable_if_t<std::is_floating_point_v<T>, T> NaNOrZero()
35{
36 return std::numeric_limits<T>::quiet_NaN();
37}
38
39template <typename T>
40std::enable_if_t<std::numeric_limits<T>::is_integer, T> NaNOrZero()
41{
42 return 0;
43}
44
45template <typename T>
46std::enable_if_t<std::is_class_v<T>, T> NaNOrZero()
47{
48 return T{};
49}
50
51#if 1 /// __int128
52template <typename T>
53std::enable_if_t<std::is_same_v<T, __int128> && !std::numeric_limits<T>::is_integer, __int128> NaNOrZero()
54{
55 return __int128(0);
56}
57#endif
58