issignaling.hpp 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. // Copyright 2023 Matt Borland
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // https://www.boost.org/LICENSE_1_0.txt
  4. #ifndef BOOST_CHARCONV_DETAIL_ISSIGNALING_HPP
  5. #define BOOST_CHARCONV_DETAIL_ISSIGNALING_HPP
  6. #include <boost/charconv/detail/config.hpp>
  7. #include <boost/charconv/detail/bit_layouts.hpp>
  8. #include <cstdint>
  9. #include <cstring>
  10. namespace boost { namespace charconv { namespace detail {
  11. template <typename T>
  12. inline bool issignaling BOOST_PREVENT_MACRO_SUBSTITUTION (T x) noexcept;
  13. #if BOOST_CHARCONV_LDBL_BITS == 128 || defined(BOOST_CHARCONV_HAS_FLOAT128)
  14. struct words128
  15. {
  16. #if BOOST_CHARCONV_ENDIAN_LITTLE_BYTE
  17. std::uint64_t lo;
  18. std::uint64_t hi;
  19. #else
  20. std::uint64_t hi;
  21. std::uint64_t lo;
  22. #endif
  23. };
  24. template <typename T>
  25. inline bool issignaling BOOST_PREVENT_MACRO_SUBSTITUTION (T x) noexcept
  26. {
  27. words128 bits;
  28. std::memcpy(&bits, &x, sizeof(T));
  29. std::uint64_t hi_word = bits.hi;
  30. std::uint64_t lo_word = bits.lo;
  31. hi_word ^= UINT64_C(0x0000800000000000);
  32. hi_word |= (lo_word | -lo_word) >> 63;
  33. return ((hi_word & INT64_MAX) > UINT64_C(0x7FFF800000000000));
  34. }
  35. #endif
  36. }}} // Namespaces
  37. #endif // BOOST_CHARCONV_DETAIL_ISSIGNALING_HPP