gnss-sim/3rdparty/boost/charconv/detail/issignaling.hpp

86 lines
1.9 KiB
C++

// Copyright 2023 Matt Borland
// Distributed under the Boost Software License, Version 1.0.
// https://www.boost.org/LICENSE_1_0.txt
#ifndef BOOST_CHARCONV_DETAIL_ISSIGNALING_HPP
#define BOOST_CHARCONV_DETAIL_ISSIGNALING_HPP
#include <boost/charconv/detail/config.hpp>
#include <boost/charconv/detail/bit_layouts.hpp>
#include <cstdint>
#include <cstring>
namespace boost { namespace charconv { namespace detail {
template <typename T>
inline bool issignaling BOOST_PREVENT_MACRO_SUBSTITUTION (T x) noexcept;
#if BOOST_CHARCONV_LDBL_BITS == 128
struct words128
{
#if BOOST_CHARCONV_ENDIAN_LITTLE_BYTE
std::uint64_t lo;
std::uint64_t hi;
#else
std::uint64_t hi;
std::uint64_t lo;
#endif
};
template <typename T>
inline bool issignaling BOOST_PREVENT_MACRO_SUBSTITUTION (T x) noexcept
{
words128 bits;
std::memcpy(&bits, &x, sizeof(T));
std::uint64_t hi_word = bits.hi;
std::uint64_t lo_word = bits.lo;
hi_word ^= UINT64_C(0x0000800000000000);
hi_word |= (lo_word | -lo_word) >> 63;
return ((hi_word & INT64_MAX) > UINT64_C(0x7FFF800000000000));
}
#endif
// 16-bit non-finite bit values:
//
// float16_t
// SNAN: 0x7D00
// QNAN: 0x7E00
// INF: 0x7C00
//
// bfloat16_t
// SNAN: 0x7FA0
// QNAN: 0x7FC0
// INF: 0x7F80
#ifdef BOOST_CHARCONV_HAS_FLOAT16
template <>
inline bool issignaling<std::float16_t> BOOST_PREVENT_MACRO_SUBSTITUTION (std::float16_t x) noexcept
{
std::uint16_t bits;
std::memcpy(&bits, &x, sizeof(std::uint16_t));
return bits >= UINT16_C(0x7D00) && bits < UINT16_C(0x7E00);
}
#endif
#ifdef BOOST_CHARCONV_HAS_BRAINFLOAT16
template <>
inline bool issignaling<std::bfloat16_t> BOOST_PREVENT_MACRO_SUBSTITUTION (std::bfloat16_t x) noexcept
{
std::uint16_t bits;
std::memcpy(&bits, &x, sizeof(std::uint16_t));
return bits >= UINT16_C(0x7FA0) && bits < UINT16_C(0x7FC0);
}
#endif
}}} // Namespaces
#endif // BOOST_CHARCONV_DETAIL_ISSIGNALING_HPP