issignaling.hpp 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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
  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. // 16-bit non-finite bit values:
  37. //
  38. // float16_t
  39. // SNAN: 0x7D00
  40. // QNAN: 0x7E00
  41. // INF: 0x7C00
  42. //
  43. // bfloat16_t
  44. // SNAN: 0x7FA0
  45. // QNAN: 0x7FC0
  46. // INF: 0x7F80
  47. #ifdef BOOST_CHARCONV_HAS_FLOAT16
  48. template <>
  49. inline bool issignaling<std::float16_t> BOOST_PREVENT_MACRO_SUBSTITUTION (std::float16_t x) noexcept
  50. {
  51. std::uint16_t bits;
  52. std::memcpy(&bits, &x, sizeof(std::uint16_t));
  53. return bits >= UINT16_C(0x7D00) && bits < UINT16_C(0x7E00);
  54. }
  55. #endif
  56. #ifdef BOOST_CHARCONV_HAS_BRAINFLOAT16
  57. template <>
  58. inline bool issignaling<std::bfloat16_t> BOOST_PREVENT_MACRO_SUBSTITUTION (std::bfloat16_t x) noexcept
  59. {
  60. std::uint16_t bits;
  61. std::memcpy(&bits, &x, sizeof(std::uint16_t));
  62. return bits >= UINT16_C(0x7FA0) && bits < UINT16_C(0x7FC0);
  63. }
  64. #endif
  65. }}} // Namespaces
  66. #endif // BOOST_CHARCONV_DETAIL_ISSIGNALING_HPP