#pragma once namespace rawaccel { constexpr double minsd(double a, double b) { return (a < b) ? a : b; } constexpr double maxsd(double a, double b) { return (b < a) ? a : b; } constexpr double clampsd(double v, double lo, double hi) { return minsd(maxsd(v, lo), hi); } template constexpr const T& min(const T& a, const T& b) { return (b < a) ? b : a; } template constexpr const T& max(const T& a, const T& b) { return (b < a) ? a : b; } template constexpr const T& clamp(const T& v, const T& lo, const T& hi) { return (v < lo) ? lo : (hi < v) ? hi : v; } // returns the unbiased exponent of x if x is normal inline int ilogb(double x) { union { double f; unsigned long long i; } u = { x }; return static_cast((u.i >> 52) & 0x7ff) - 0x3ff; } // returns x * 2^n if n is in [-1022, 1023] inline double scalbn(double x, int n) { union { double f; unsigned long long i; } u; u.i = static_cast(0x3ff + n) << 52; return x * u.f; } inline bool infnan(double x) { return ilogb(x) == 0x400; } struct noop { template constexpr void operator()(Ts&&...) const noexcept {} }; template struct remove_ref { using type = T; }; template struct remove_ref { using type = T; }; template struct remove_ref { using type = T; }; template using remove_ref_t = typename remove_ref::type; template struct is_same { static constexpr bool value = false; }; template struct is_same { static constexpr bool value = true; }; template inline constexpr bool is_same_v = is_same::value; template struct is_rvalue_ref { static constexpr bool value = false; }; template struct is_rvalue_ref { static constexpr bool value = true; }; template inline constexpr bool is_rvalue_ref_v = is_rvalue_ref::value; }