// Distributed under the Boost Software License Version 1.0 https://www.boost.org/LICENSE_1_0.txt // Copyright Gero Peterhoff #ifndef BOOST_CONFIG_FLOAT_HPP #define BOOST_CONFIG_FLOAT_HPP #include #include #if !defined(BOOST_NO_CXX23_HDR_STDFLOAT) #include #endif namespace boost { // BOOST_HAS_FLOAT128 is available #if defined(BOOST_CSTDFLOAT_FLOAT80_NATIVE_TYPE) #define BOOST_HAS_FLOAT80 #endif #if defined(BOOST_CSTDFLOAT_FLOAT64_NATIVE_TYPE) #define BOOST_HAS_FLOAT64 #endif #if defined(BOOST_CSTDFLOAT_FLOAT32_NATIVE_TYPE) #define BOOST_HAS_FLOAT32 #endif #if defined(BOOST_CSTDFLOAT_FLOAT16_NATIVE_TYPE) #define BOOST_HAS_FLOAT16 #endif #if defined(BOOST_HAS_FLOAT128) || defined(__STDCPP_FLOAT128_T__) // https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format // todo correct/complete ? // todo riscv Q subset #if defined(BOOST_ARCH_Z_AVAILABLE) || \ defined(BOOST_ARCH_PARISC_AVAILABLE) || \ defined(BOOST_ARCH_SYS390_AVAILABLE) || \ defined(BOOST_ARCH_RISCV_AVAILABLE) || \ (defined(BOOST_ARCH_SPARC_AVAILABLE) && (BOOST_ARCH_SPARC >= 8)) #define BOOST_HAS_NATIVE_FLOAT128 #endif #endif #if defined(BOOST_HAS_FLOAT80) // todo only on x86-HW ? #if defined(BOOST_ARCH_X86_AVAILABLE) #define BOOST_HAS_NATIVE_FLOAT80 #endif #endif #if defined(BOOST_HAS_FLOAT64) || defined(__STDCPP_FLOAT64_T__) // todo correct/complete ? #define BOOST_HAS_NATIVE_FLOAT64 #endif #if defined(BOOST_HAS_FLOAT32) || defined(__STDCPP_FLOAT32_T__) // todo correct/complete ? #define BOOST_HAS_NATIVE_FLOAT32 #endif #if defined(__STDCPP_BFLOAT16_T__) // no known HW-implementation // __AVX512BF16__ contains only conversions and no arithmetic operations // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#avx512techs=AVX512_BF16 #if (0 != 0) #define BOOST_HAS_NATIVE_BFLOAT16 #endif #endif #if defined(BOOST_HAS_FLOAT16) || defined(__STDCPP_FLOAT16_T__) // todo correct/complete ? // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#avx512techs=AVX512_FP16 #if defined(__AVX512FP16__) || \ (defined(BOOST_ARCH_ARM_AVAILABLE) && (BOOST_ARCH_ARM >= 8)) #define BOOST_HAS_NATIVE_FLOAT16 #endif #endif namespace platform { // provides correct min/max-types #if defined(BOOST_HAS_FLOAT128) || defined(__STDCPP_FLOAT128_T__) #if defined(__STDCPP_FLOAT128_T__) using floatmax_t = std::float128_t; #else using floatmax_t = boost::float128_t; #endif #elif defined(BOOST_HAS_FLOAT80) using floatmax_t = boost::float80_t; #elif defined(BOOST_HAS_FLOAT64) || defined(__STDCPP_FLOAT64_T__) #if defined(__STDCPP_FLOAT64_T__) using floatmax_t = std::float64_t; #else using floatmax_t = boost::float64_t; #endif #elif defined(BOOST_HAS_FLOAT32) || defined(__STDCPP_FLOAT32_T__) #if defined(__STDCPP_FLOAT32_T__) using floatmax_t = std::float32_t; #else using floatmax_t = boost::float32_t; #endif #elif defined(__STDCPP_BFLOAT16_T__) using floatmax_t = std::bfloat16_t; #elif defined(BOOST_HAS_FLOAT16) || defined(__STDCPP_FLOAT16_T__) #if defined(__STDCPP_FLOAT16_T__) using floatmax_t = std::float16_t; #else using floatmax_t = boost::float16_t; #endif #else static_assert(false); #endif #if defined(BOOST_HAS_FLOAT16) || defined(__STDCPP_FLOAT16_T__) #if defined(__STDCPP_FLOAT16_T__) using floatmin_t = std::float16_t; #else using floatmin_t = boost::float16_t; #endif #elif defined(__STDCPP_BFLOAT16_T__) using floatmin_t = std::bfloat16_t; #elif defined(BOOST_HAS_FLOAT32) || defined(__STDCPP_FLOAT32_T__) #if defined(__STDCPP_FLOAT32_T__) using floatmin_t = std::float32_t; #else using floatmin_t = boost::float32_t; #endif #elif defined(BOOST_HAS_FLOAT64) || defined(__STDCPP_FLOAT64_T__) #if defined(__STDCPP_FLOAT64_T__) using floatmin_t = std::float64_t; #else using floatmin_t = boost::float64_t; #endif #elif defined(BOOST_HAS_FLOAT80) using floatmin_t = float80_t; #elif defined(BOOST_HAS_FLOAT128) || defined(__STDCPP_FLOAT128_T__) #if defined(__STDCPP_FLOAT128_T__) using floatmin_t = std::float128_t; #else using floatmin_t = boost::float128_t; #endif #else static_assert(false); #endif } // platform } // boost #endif // BOOST_CONFIG_FLOAT_HPP