namespace std { namespace detail { template struct type_floating_point { static_assert(std::is_arithmetic_v, "invalid type"); using type = std::conditional_t, Type, float64_t>; }; } // detail template using floating_point_t = typename detail::type_floating_point::type; // is float80_t template struct is_float80 : public bool_constant < #if defined(BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE) is_same_v #else false #endif > {}; template inline constexpr bool is_float80_v = is_float80::value; // arithmetic template concept arithmetic = is_arithmetic_v; // combined nan/inf template [[nodiscard]] inline constexpr bool isnaninf(const Type a) noexcept { if constexpr (is_floating_point_v) return bool(int(isnan(a)) | int(isinf(a))); else return false; } template [[nodiscard]] inline constexpr floating_point_t sgn(const Type a) noexcept { using value_type = floating_point_t; auto calc = [&]() constexpr noexcept { if constexpr (is_floating_point_v) { auto get_one_zero = [&]() constexpr noexcept -> value_type { // abs reduces/prevents double conditional jumps return (abs(a) > 0) ? value_type{1} : value_type{0}; }; if constexpr (is_float80_v) { // optimized for float80_t if supported const bool ni = isnaninf(a); const float80_t oz = get_one_zero(); return copysign(ni ? a : oz, a); } else { // generate better/smaller code in vector/loop-context than isnaninf(a) ? a : copysign(get_one_zero(), a); return !isnaninf(a) ? copysign(get_one_zero(), a) : a; //return isnaninf(a) ? a : copysign(get_one_zero(), a); } } else if constexpr (is_same_v) { // fukking bool in arithmetic return int(a); } else { if constexpr (is_signed_v) return int(int(a>0) - int(a<0)); else return int(a>0); } }; return value_type(calc()); } } // std