OSSIA
Open Scenario System for Interactive Application
Loading...
Searching...
No Matches
safe_math.hpp
1#pragma once
2#include <ossia/detail/config.hpp>
3
4#include <cmath>
5
6namespace ossia
7{
8
9OSSIA_INLINE bool safe_isnan(double val) noexcept
10{
11#if __FINITE_MATH_ONLY__
12#if defined(_MSC_VER)
13 return std::isnan(val);
14#elif defined(__APPLE__)
15 return __isnand(val);
16#elif defined(__EMSCRIPTEN__)
17 return __fpclassifyl(val) == FP_NAN;
18#else
19 // On gcc / clang, with -ffast-math, std::isnan always returns 0
20 // There's __isnan but it's not always available.
21 union
22 {
23 double fp;
24 uint64_t bits;
25 } num{.fp = val};
26
27 return ((unsigned)(num.bits >> 32) & 0x7fffffff) + ((unsigned)num.bits != 0)
28 > 0x7ff00000;
29#endif
30#else
31 return std::isnan(val);
32#endif
33}
34
35OSSIA_INLINE bool safe_isfinite(double val) noexcept
36{
37#if __FINITE_MATH_ONLY__
38#if defined(_MSC_VER)
39 return std::isfinite(val);
40#elif defined(__APPLE__)
41 return __isfinited(val);
42#elif defined(__EMSCRIPTEN__)
43 const auto cls = __fpclassifyl(val);
44 return cls != FP_NAN && cls != FP_INFINITE;
45#else
46 // On gcc / clang, with -ffast-math, std::isfinite always returns 1.
47 // NaN and infinity are exactly the values whose exponent field is all ones
48 // and nothing else is, so unlike the two predicates above this needs only
49 // one test and does not have to look at the mantissa at all.
50 union
51 {
52 double fp;
53 uint64_t bits;
54 } num{.fp = val};
55
56 return ((unsigned)(num.bits >> 32) & 0x7ff00000) != 0x7ff00000;
57#endif
58#else
59 return std::isfinite(val);
60#endif
61}
62
63OSSIA_INLINE bool safe_isinf(double val) noexcept
64{
65#if __FINITE_MATH_ONLY__
66#if defined(_MSC_VER)
67 return std::isinf(val);
68#elif defined(__APPLE__)
69 return __isinfd(val);
70#elif defined(__EMSCRIPTEN__)
71 return __fpclassifyl(val) == FP_INFINITE;
72#else
73 // On gcc / clang, with -ffast-math, std::isinf always returns 0
74 // There's __isinf but it's not always available.
75 union
76 {
77 double fp;
78 uint64_t bits;
79 } num{.fp = val};
80
81 return ((unsigned)(num.bits >> 32) & 0x7fffffff) == 0x7ff00000
82 && (unsigned)num.bits == 0;
83#endif
84#else
85 return std::isinf(val);
86#endif
87}
88
89}
Definition git_info.h:7