Hi! The following patch is partial support for std::float{16,32,64,128}_t in libstdc++. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1467r9.html says that <ostream>, <istream>, <charconv>, <cmath> and <complex> need changes too, but before doing that, it would be nice to get an agreement on what macros to use etc. The support for cmath/complex is possible in multiple ways: 1) glibc >= 2.26 support whatever{f32,f64,f128} APIs next to whatever{f,,l} APIs, so I think we can use __builtin_sin{f32,f64,f128} etc. to support _Float{32,64,128} overloads 2) if not, pretty much everywhere float is actually the same mode as _Float32 and double as _Float64, I guess one could use guards like #if __FLT32_MANT_DIG__ == __FLT_MANT_DIG__ \ && __FLT32_MAX_EXP__ == __FLT_MAX_EXP__ or #if __FLT64_MANT_DIG__ == __DBL_MANT_DIG__ \ && __FLT64_MAX_EXP__ == __DBL_MAX_EXP__ or even #if __FLT128_MANT_DIG__ == __LDBL_MANT_DIG__ \ && __FLT128_MAX_EXP__ == __LDBL_MAX_EXP__ for the few arches like aarch64 where long double and _Float128 has the same mode. Then we can use __builtin_sin{f,,l} etc. to support _Float{32,64,128} overloads 3) not sure what to do as fallback if neither 1) nor 2) work out, not provide the overloads, or even undef __STDCPP_FLOAT32_T__ etc. in the library? 4) AFAIK glibc doesn't have _Float16 APIs, so we need to widen and use __builtin_sinf32 1) or __builtin_sinf 2) for _Float16 and explicitly do narrowing cast 5) bfloat16_t needs more work even on the compiler side, but once the support is there and in stdfloat and other headers touched by the patch below (testcases already include bfloat16_t though), it will need something like 4) too.
The patch also doesn't include any testcases to cover the <type_traits> changes, it isn't clear to me where to put that. Tested on x86_64-linux. 2022-09-27 Jakub Jelinek <ja...@redhat.com> * include/std/stdfloat: New file. * include/std/numbers (__glibcxx_numbers): Define and use it for __float128 explicit instantiations as well as _Float{16,32,64,128}. * include/std/atomic (atomic<_Float16>, atomic<_Float32>, atomic<_Float64>, atomic<_Float128>): New explicit instantiations. * include/std/type_traits (__is_floating_point_helper<_Float16>, __is_floating_point_helper<_Float32>, __is_floating_point_helper<_Float64>, __is_floating_point_helper<_Float128>): Likewise. * include/std/limits (__glibcxx_concat3_, __glibcxx_concat3, __glibcxx_float_n): Define. (numeric_limits<_Float16>, numeric_limits<_Float32>, numeric_limits<_Float64>, numeric_limits<_Float128>): New explicit instantiations. * include/Makefile.am (std_headers): Add stdfloat. * include/Makefile.in: Regenerated. * include/precompiled/stdc++.h: Include stdfloat. * testsuite/18_support/headers/stdfloat/types_std.cc: New test. * testsuite/18_support/headers/limits/synopsis_cxx23.cc: New test. * testsuite/26_numerics/numbers/4.cc: New test. * testsuite/29_atomics/atomic_float/requirements_cxx23.cc: New test. --- libstdc++-v3/include/std/stdfloat.jj 2022-09-27 08:49:45.932769534 +0200 +++ libstdc++-v3/include/std/stdfloat 2022-09-27 08:49:45.932769534 +0200 @@ -0,0 +1,58 @@ +// <stdfloat> -*- C++ -*- + +// Copyright (C) 2022 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/** @file include/stdfloat + * This is a Standard C++ Library header. + */ + +#ifndef _GLIBCXX_STDFLOAT +#define _GLIBCXX_STDFLOAT 1 + +#if __cplusplus > 202002L +#include <bits/c++config.h> + +namespace std +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + #ifdef __STDCPP_FLOAT16_T__ + using float16_t = _Float16; + #endif + + #ifdef __STDCPP_FLOAT32_T__ + using float32_t = _Float32; + #endif + + #ifdef __STDCPP_FLOAT64_T__ + using float64_t = _Float64; + #endif + + #ifdef __STDCPP_FLOAT128_T__ + using float128_t = _Float128; + #endif + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std +#endif // C++23 +#endif // _GLIBCXX_STDFLOAT --- libstdc++-v3/include/std/numbers.jj 2022-01-11 22:31:41.525756652 +0100 +++ libstdc++-v3/include/std/numbers 2022-09-27 08:49:45.933769521 +0200 @@ -133,72 +133,94 @@ namespace numbers inline constexpr double egamma = egamma_v<double>; inline constexpr double phi = phi_v<double>; +#define __glibcxx_numbers(TYPE, SUFFIX) \ + /* e */ \ + template<> \ + inline constexpr TYPE e_v<TYPE> \ + = 2.718281828459045235360287471352662498##SUFFIX; \ + \ + /* log_2 e */ \ + template<> \ + inline constexpr TYPE log2e_v<TYPE> \ + = 1.442695040888963407359924681001892137##SUFFIX; \ + \ + /* log_10 e */ \ + template<> \ + inline constexpr TYPE log10e_v<TYPE> \ + = 0.434294481903251827651128918916605082##SUFFIX; \ + \ + /* pi */ \ + template<> \ + inline constexpr TYPE pi_v<TYPE> \ + = 3.141592653589793238462643383279502884##SUFFIX; \ + \ + /* 1/pi */ \ + template<> \ + inline constexpr TYPE inv_pi_v<TYPE> \ + = 0.318309886183790671537767526745028724##SUFFIX; \ + \ + /* 1/sqrt(pi) */ \ + template<> \ + inline constexpr TYPE inv_sqrtpi_v<TYPE> \ + = 0.564189583547756286948079451560772586##SUFFIX; \ + \ + /* log_e 2 */ \ + template<> \ + inline constexpr TYPE ln2_v<TYPE> \ + = 0.693147180559945309417232121458176568##SUFFIX; \ + \ + /* log_e 10 */ \ + template<> \ + inline constexpr TYPE ln10_v<TYPE> \ + = 2.302585092994045684017991454684364208##SUFFIX; \ + \ + /* sqrt(2) */ \ + template<> \ + inline constexpr TYPE sqrt2_v<TYPE> \ + = 1.414213562373095048801688724209698079##SUFFIX; \ + \ + /* sqrt(3) */ \ + template<> \ + inline constexpr TYPE sqrt3_v<TYPE> \ + = 1.732050807568877293527446341505872367##SUFFIX; \ + \ + /* 1/sqrt(3) */ \ + template<> \ + inline constexpr TYPE inv_sqrt3_v<TYPE> \ + = 0.577350269189625764509148780501957456##SUFFIX; \ + \ + /* The Euler-Mascheroni constant */ \ + template<> \ + inline constexpr TYPE egamma_v<TYPE> \ + = 0.577215664901532860606512090082402431##SUFFIX; \ + \ + /* The golden ratio, (1+sqrt(5))/2 */ \ + template<> \ + inline constexpr TYPE phi_v<TYPE> \ + = 1.618033988749894848204586834365638118##SUFFIX + +#ifdef __STDCPP_FLOAT16_T__ +__glibcxx_numbers (_Float16, F16); +#endif + +#ifdef __STDCPP_FLOAT32_T__ +__glibcxx_numbers (_Float32, F32); +#endif + +#ifdef __STDCPP_FLOAT64_T__ +__glibcxx_numbers (_Float64, F64); +#endif + +#ifdef __STDCPP_FLOAT128_T__ +__glibcxx_numbers (_Float128, F128); +#endif + #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) - template<> - inline constexpr __float128 e_v<__float128> - = 2.718281828459045235360287471352662498Q; - - /// log_2 e - template<> - inline constexpr __float128 log2e_v<__float128> - = 1.442695040888963407359924681001892137Q; - - /// log_10 e - template<> - inline constexpr __float128 log10e_v<__float128> - = 0.434294481903251827651128918916605082Q; - - /// pi - template<> - inline constexpr __float128 pi_v<__float128> - = 3.141592653589793238462643383279502884Q; - - /// 1/pi - template<> - inline constexpr __float128 inv_pi_v<__float128> - = 0.318309886183790671537767526745028724Q; - - /// 1/sqrt(pi) - template<> - inline constexpr __float128 inv_sqrtpi_v<__float128> - = 0.564189583547756286948079451560772586Q; - - /// log_e 2 - template<> - inline constexpr __float128 ln2_v<__float128> - = 0.693147180559945309417232121458176568Q; - - /// log_e 10 - template<> - inline constexpr __float128 ln10_v<__float128> - = 2.302585092994045684017991454684364208Q; - - /// sqrt(2) - template<> - inline constexpr __float128 sqrt2_v<__float128> - = 1.414213562373095048801688724209698079Q; - - /// sqrt(3) - template<> - inline constexpr __float128 sqrt3_v<__float128> - = 1.732050807568877293527446341505872367Q; - - /// 1/sqrt(3) - template<> - inline constexpr __float128 inv_sqrt3_v<__float128> - = 0.577350269189625764509148780501957456Q; - - /// The Euler-Mascheroni constant - template<> - inline constexpr __float128 egamma_v<__float128> - = 0.577215664901532860606512090082402431Q; - - /// The golden ratio, (1+sqrt(5))/2 - template<> - inline constexpr __float128 phi_v<__float128> - = 1.618033988749894848204586834365638118Q; +__glibcxx_numbers (__float128, Q); #endif // USE_FLOAT128 +#undef __glibcxx_numbers + } // namespace numbers /// @} _GLIBCXX_END_NAMESPACE_VERSION --- libstdc++-v3/include/std/atomic.jj 2022-09-11 22:28:56.375164180 +0200 +++ libstdc++-v3/include/std/atomic 2022-09-27 08:49:45.934769507 +0200 @@ -1625,6 +1625,74 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION using __atomic_float<long double>::operator=; }; +#ifdef __STDCPP_FLOAT16_T__ + template<> + struct atomic<_Float16> : __atomic_float<_Float16> + { + atomic() noexcept = default; + + constexpr + atomic(_Float16 __fp) noexcept : __atomic_float<_Float16>(__fp) + { } + + atomic& operator=(const atomic&) volatile = delete; + atomic& operator=(const atomic&) = delete; + + using __atomic_float<_Float16>::operator=; + }; +#endif + +#ifdef __STDCPP_FLOAT32_T__ + template<> + struct atomic<_Float32> : __atomic_float<_Float32> + { + atomic() noexcept = default; + + constexpr + atomic(_Float32 __fp) noexcept : __atomic_float<_Float32>(__fp) + { } + + atomic& operator=(const atomic&) volatile = delete; + atomic& operator=(const atomic&) = delete; + + using __atomic_float<_Float32>::operator=; + }; +#endif + +#ifdef __STDCPP_FLOAT64_T__ + template<> + struct atomic<_Float64> : __atomic_float<_Float64> + { + atomic() noexcept = default; + + constexpr + atomic(_Float64 __fp) noexcept : __atomic_float<_Float64>(__fp) + { } + + atomic& operator=(const atomic&) volatile = delete; + atomic& operator=(const atomic&) = delete; + + using __atomic_float<_Float64>::operator=; + }; +#endif + +#ifdef __STDCPP_FLOAT128_T__ + template<> + struct atomic<_Float128> : __atomic_float<_Float128> + { + atomic() noexcept = default; + + constexpr + atomic(_Float128 __fp) noexcept : __atomic_float<_Float128>(__fp) + { } + + atomic& operator=(const atomic&) volatile = delete; + atomic& operator=(const atomic&) = delete; + + using __atomic_float<_Float128>::operator=; + }; +#endif + #define __cpp_lib_atomic_ref 201806L /// Class template to provide atomic operations on a non-atomic variable. --- libstdc++-v3/include/std/type_traits.jj 2022-09-25 22:22:03.979596700 +0200 +++ libstdc++-v3/include/std/type_traits 2022-09-27 08:49:45.934769507 +0200 @@ -459,6 +459,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION struct __is_floating_point_helper<long double> : public true_type { }; +#ifdef __STDCPP_FLOAT16_T__ + template<> + struct __is_floating_point_helper<_Float16> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT32_T__ + template<> + struct __is_floating_point_helper<_Float32> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT64_T__ + template<> + struct __is_floating_point_helper<_Float64> + : public true_type { }; +#endif + +#ifdef __STDCPP_FLOAT128_T__ + template<> + struct __is_floating_point_helper<_Float128> + : public true_type { }; +#endif + #if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128) template<> struct __is_floating_point_helper<__float128> --- libstdc++-v3/include/std/limits.jj 2022-01-11 22:31:41.525756652 +0100 +++ libstdc++-v3/include/std/limits 2022-09-27 08:49:45.933769521 +0200 @@ -1890,6 +1890,115 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #undef __glibcxx_long_double_traps #undef __glibcxx_long_double_tinyness_before +#if __cplusplus > 202202L + +#define __glibcxx_concat3_(P,M,S) P ## M ## S +#define __glibcxx_concat3(P,M,S) __glibcxx_concat3_ (P,M,S) + +#define __glibcxx_float_n(BITSIZE) \ + __extension__ \ + template<> \ + struct numeric_limits<_Float##BITSIZE> \ + { \ + static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; \ + \ + static _GLIBCXX_CONSTEXPR _Float##BITSIZE \ + min() _GLIBCXX_USE_NOEXCEPT \ + { return __glibcxx_concat3 (__FLT, BITSIZE, _MIN__); } \ + \ + static _GLIBCXX_CONSTEXPR _Float##BITSIZE \ + max() _GLIBCXX_USE_NOEXCEPT \ + { return __glibcxx_concat3 (__FLT, BITSIZE, _MAX__); } \ + \ + static _GLIBCXX_CONSTEXPR _Float##BITSIZE \ + lowest() noexcept \ + { return -__glibcxx_concat3 (__FLT, BITSIZE, _MAX__); } \ + \ + static _GLIBCXX_USE_CONSTEXPR int digits \ + = __glibcxx_concat3 (__FLT, BITSIZE, _MANT_DIG__); \ + static _GLIBCXX_USE_CONSTEXPR int digits10 \ + = __glibcxx_concat3 (__FLT, BITSIZE, _DIG__); \ + static _GLIBCXX_USE_CONSTEXPR int max_digits10 \ + = __glibcxx_max_digits10 (__glibcxx_concat3 (__FLT, BITSIZE, \ + _MANT_DIG__)); \ + static _GLIBCXX_USE_CONSTEXPR bool is_signed = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_integer = false; \ + static _GLIBCXX_USE_CONSTEXPR bool is_exact = false; \ + static _GLIBCXX_USE_CONSTEXPR int radix \ + = __glibcxx_concat3 (__FLT, BITSIZE, _RADIX__); \ + \ + static _GLIBCXX_CONSTEXPR _Float##BITSIZE \ + epsilon() _GLIBCXX_USE_NOEXCEPT \ + { return __glibcxx_concat3 (__FLT, BITSIZE, _EPSILON__); } \ + \ + static _GLIBCXX_CONSTEXPR _Float##BITSIZE \ + round_error() _GLIBCXX_USE_NOEXCEPT { return 0.5F##BITSIZE; } \ + \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent \ + = __glibcxx_concat3 (__FLT, BITSIZE, _MIN_EXP__); \ + static _GLIBCXX_USE_CONSTEXPR int min_exponent10 \ + = __glibcxx_concat3 (__FLT, BITSIZE, _MIN_10_EXP__); \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent \ + = __glibcxx_concat3 (__FLT, BITSIZE, _MAX_EXP__); \ + static _GLIBCXX_USE_CONSTEXPR int max_exponent10 \ + = __glibcxx_concat3 (__FLT, BITSIZE, _MAX_10_EXP__); \ + \ + static _GLIBCXX_USE_CONSTEXPR bool has_infinity \ + = __glibcxx_concat3 (__FLT, BITSIZE, _HAS_INFINITY__); \ + static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN \ + = __glibcxx_concat3 (__FLT, BITSIZE, _HAS_QUIET_NAN__); \ + static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN \ + = has_quiet_NaN; \ + static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm \ + = bool(__glibcxx_concat3 (__FLT, BITSIZE, _HAS_DENORM__)) \ + ? denorm_present : denorm_absent; \ + static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; \ + \ + static _GLIBCXX_CONSTEXPR _Float##BITSIZE \ + infinity() _GLIBCXX_USE_NOEXCEPT \ + { return __builtin_huge_valf##BITSIZE(); } \ + \ + static _GLIBCXX_CONSTEXPR _Float##BITSIZE \ + quiet_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return __builtin_nanf##BITSIZE(""); } \ + \ + static _GLIBCXX_CONSTEXPR _Float##BITSIZE \ + signaling_NaN() _GLIBCXX_USE_NOEXCEPT \ + { return __builtin_nansf##BITSIZE(""); } \ + \ + static _GLIBCXX_CONSTEXPR _Float##BITSIZE \ + denorm_min() _GLIBCXX_USE_NOEXCEPT \ + { return __glibcxx_concat3 (__FLT, BITSIZE, _DENORM_MIN__); } \ + \ + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 \ + = as_infinity && has_quiet_NaN && has_denorm == denorm_present; \ + static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; \ + static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; \ + \ + static _GLIBCXX_USE_CONSTEXPR bool traps = false; \ + static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; \ + static _GLIBCXX_USE_CONSTEXPR float_round_style round_style \ + = round_to_nearest; \ + }; \ + +#ifdef __STDCPP_FLOAT16_T__ +__glibcxx_float_n(16) +#endif +#ifdef __STDCPP_FLOAT32_T__ +__glibcxx_float_n(32) +#endif +#ifdef __STDCPP_FLOAT64_T__ +__glibcxx_float_n(64) +#endif +#ifdef __STDCPP_FLOAT128_T__ +__glibcxx_float_n(128) +#endif +#undef __glibcxx_float_n +#undef __glibcxx_concat3 +#undef __glibcxx_concat3_ + +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace --- libstdc++-v3/include/Makefile.am.jj 2022-08-10 23:16:41.981479135 +0200 +++ libstdc++-v3/include/Makefile.am 2022-09-27 09:33:16.838564748 +0200 @@ -83,6 +83,7 @@ std_headers = \ ${std_srcdir}/stack \ ${std_srcdir}/stacktrace \ ${std_srcdir}/stdexcept \ + ${std_srcdir}/stdfloat \ ${std_srcdir}/stop_token \ ${std_srcdir}/streambuf \ ${std_srcdir}/string \ --- libstdc++-v3/include/Makefile.in.jj 2022-08-10 23:16:41.982479122 +0200 +++ libstdc++-v3/include/Makefile.in 2022-09-27 09:33:30.089386201 +0200 @@ -441,6 +441,7 @@ std_headers = \ ${std_srcdir}/stack \ ${std_srcdir}/stacktrace \ ${std_srcdir}/stdexcept \ + ${std_srcdir}/stdfloat \ ${std_srcdir}/stop_token \ ${std_srcdir}/streambuf \ ${std_srcdir}/string \ --- libstdc++-v3/include/precompiled/stdc++.h.jj 2022-05-23 21:44:49.094846916 +0200 +++ libstdc++-v3/include/precompiled/stdc++.h 2022-09-27 08:49:45.932769534 +0200 @@ -159,4 +159,5 @@ # include <stacktrace> #endif #include <stdatomic.h> +#include <stdfloat> #endif --- libstdc++-v3/testsuite/18_support/headers/stdfloat/types_std.cc.jj 2022-09-27 08:56:15.806529350 +0200 +++ libstdc++-v3/testsuite/18_support/headers/stdfloat/types_std.cc 2022-09-27 09:26:58.681660524 +0200 @@ -0,0 +1,40 @@ +// { dg-options "-std=gnu++2b" } +// { dg-do compile { target c++23 } } + +// Copyright (C) 2022 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <stdfloat> + +namespace gnu +{ +#if defined(__STDCPP_FLOAT16_T__) + typedef std::float16_t t1; +#endif +#if defined(__STDCPP_FLOAT32_T__) + typedef std::float32_t t2; +#endif +#if defined(__STDCPP_FLOAT64_T__) + typedef std::float64_t t3; +#endif +#if defined(__STDCPP_FLOAT128_T__) + typedef std::float128_t t4; +#endif +#if defined(__STDCPP_BFLOAT16_T__) + typedef std::bfloat16_t t5; +#endif +} --- libstdc++-v3/testsuite/18_support/headers/limits/synopsis_cxx23.cc.jj 2022-09-27 09:00:16.815274177 +0200 +++ libstdc++-v3/testsuite/18_support/headers/limits/synopsis_cxx23.cc 2022-09-27 09:26:44.055857783 +0200 @@ -0,0 +1,43 @@ +// { dg-options "-std=gnu++2b" } +// { dg-do compile { target c++23 } } +// { dg-require-normal-namespace "" } + +// Copyright (C) 2022 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +#include <limits> +#include <stdfloat> + +namespace std { + template<class T> class numeric_limits; + +#if defined(__STDCPP_FLOAT16_T__) + template<> class numeric_limits<float16_t>; +#endif +#if defined(__STDCPP_FLOAT32_T__) + template<> class numeric_limits<float32_t>; +#endif +#if defined(__STDCPP_FLOAT64_T__) + template<> class numeric_limits<float64_t>; +#endif +#if defined(__STDCPP_FLOAT128_T__) + template<> class numeric_limits<float128_t>; +#endif +#if defined(__STDCPP_BFLOAT16_T__) + template<> class numeric_limits<bfloat16_t>; +#endif +} --- libstdc++-v3/testsuite/26_numerics/numbers/4.cc.jj 2022-09-27 09:04:07.578159213 +0200 +++ libstdc++-v3/testsuite/26_numerics/numbers/4.cc 2022-09-27 09:06:44.603039943 +0200 @@ -0,0 +1,122 @@ +// Copyright (C) 2022 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++2b" } +// { dg-do compile { target c++23 } } + +#include <numbers> +#include <stdfloat> + +#if defined(__STDCPP_FLOAT16_T__) +void +test01() +{ + const std::float16_t* d1 = &std::numbers::e_v<std::float16_t>; + const std::float16_t* d2 = &std::numbers::log2e_v<std::float16_t>; + const std::float16_t* d3 = &std::numbers::log10e_v<std::float16_t>; + const std::float16_t* d4 = &std::numbers::pi_v<std::float16_t>; + const std::float16_t* d5 = &std::numbers::inv_pi_v<std::float16_t>; + const std::float16_t* d6 = &std::numbers::inv_sqrtpi_v<std::float16_t>; + const std::float16_t* d7 = &std::numbers::ln2_v<std::float16_t>; + const std::float16_t* d8 = &std::numbers::ln10_v<std::float16_t>; + const std::float16_t* d9 = &std::numbers::sqrt2_v<std::float16_t>; + const std::float16_t* d10 = &std::numbers::sqrt3_v<std::float16_t>; + const std::float16_t* d11 = &std::numbers::inv_sqrt3_v<std::float16_t>; + const std::float16_t* d12 = &std::numbers::egamma_v<std::float16_t>; + const std::float16_t* d13 = &std::numbers::phi_v<std::float16_t>; +} +#endif + +#if defined(__STDCPP_FLOAT32_T__) +void +test02() +{ + const std::float32_t* d1 = &std::numbers::e_v<std::float32_t>; + const std::float32_t* d2 = &std::numbers::log2e_v<std::float32_t>; + const std::float32_t* d3 = &std::numbers::log10e_v<std::float32_t>; + const std::float32_t* d4 = &std::numbers::pi_v<std::float32_t>; + const std::float32_t* d5 = &std::numbers::inv_pi_v<std::float32_t>; + const std::float32_t* d6 = &std::numbers::inv_sqrtpi_v<std::float32_t>; + const std::float32_t* d7 = &std::numbers::ln2_v<std::float32_t>; + const std::float32_t* d8 = &std::numbers::ln10_v<std::float32_t>; + const std::float32_t* d9 = &std::numbers::sqrt2_v<std::float32_t>; + const std::float32_t* d10 = &std::numbers::sqrt3_v<std::float32_t>; + const std::float32_t* d11 = &std::numbers::inv_sqrt3_v<std::float32_t>; + const std::float32_t* d12 = &std::numbers::egamma_v<std::float32_t>; + const std::float32_t* d13 = &std::numbers::phi_v<std::float32_t>; +} +#endif + +#if defined(__STDCPP_FLOAT64_T__) +void +test03() +{ + const std::float64_t* d1 = &std::numbers::e_v<std::float64_t>; + const std::float64_t* d2 = &std::numbers::log2e_v<std::float64_t>; + const std::float64_t* d3 = &std::numbers::log10e_v<std::float64_t>; + const std::float64_t* d4 = &std::numbers::pi_v<std::float64_t>; + const std::float64_t* d5 = &std::numbers::inv_pi_v<std::float64_t>; + const std::float64_t* d6 = &std::numbers::inv_sqrtpi_v<std::float64_t>; + const std::float64_t* d7 = &std::numbers::ln2_v<std::float64_t>; + const std::float64_t* d8 = &std::numbers::ln10_v<std::float64_t>; + const std::float64_t* d9 = &std::numbers::sqrt2_v<std::float64_t>; + const std::float64_t* d10 = &std::numbers::sqrt3_v<std::float64_t>; + const std::float64_t* d11 = &std::numbers::inv_sqrt3_v<std::float64_t>; + const std::float64_t* d12 = &std::numbers::egamma_v<std::float64_t>; + const std::float64_t* d13 = &std::numbers::phi_v<std::float64_t>; +} +#endif + +#if defined(__STDCPP_FLOAT128_T__) +void +test04() +{ + const std::float128_t* d1 = &std::numbers::e_v<std::float128_t>; + const std::float128_t* d2 = &std::numbers::log2e_v<std::float128_t>; + const std::float128_t* d3 = &std::numbers::log10e_v<std::float128_t>; + const std::float128_t* d4 = &std::numbers::pi_v<std::float128_t>; + const std::float128_t* d5 = &std::numbers::inv_pi_v<std::float128_t>; + const std::float128_t* d6 = &std::numbers::inv_sqrtpi_v<std::float128_t>; + const std::float128_t* d7 = &std::numbers::ln2_v<std::float128_t>; + const std::float128_t* d8 = &std::numbers::ln10_v<std::float128_t>; + const std::float128_t* d9 = &std::numbers::sqrt2_v<std::float128_t>; + const std::float128_t* d10 = &std::numbers::sqrt3_v<std::float128_t>; + const std::float128_t* d11 = &std::numbers::inv_sqrt3_v<std::float128_t>; + const std::float128_t* d12 = &std::numbers::egamma_v<std::float128_t>; + const std::float128_t* d13 = &std::numbers::phi_v<std::float128_t>; +} +#endif + +#if defined(__STDCPP_BFLOAT16_T__) +void +test05() +{ + const std::bfloat16_t* d1 = &std::numbers::e_v<std::bfloat16_t>; + const std::bfloat16_t* d2 = &std::numbers::log2e_v<std::bfloat16_t>; + const std::bfloat16_t* d3 = &std::numbers::log10e_v<std::bfloat16_t>; + const std::bfloat16_t* d4 = &std::numbers::pi_v<std::bfloat16_t>; + const std::bfloat16_t* d5 = &std::numbers::inv_pi_v<std::bfloat16_t>; + const std::bfloat16_t* d6 = &std::numbers::inv_sqrtpi_v<std::bfloat16_t>; + const std::bfloat16_t* d7 = &std::numbers::ln2_v<std::bfloat16_t>; + const std::bfloat16_t* d8 = &std::numbers::ln10_v<std::bfloat16_t>; + const std::bfloat16_t* d9 = &std::numbers::sqrt2_v<std::bfloat16_t>; + const std::bfloat16_t* d10 = &std::numbers::sqrt3_v<std::bfloat16_t>; + const std::bfloat16_t* d11 = &std::numbers::inv_sqrt3_v<std::bfloat16_t>; + const std::bfloat16_t* d12 = &std::numbers::egamma_v<std::bfloat16_t>; + const std::bfloat16_t* d13 = &std::numbers::phi_v<std::bfloat16_t>; +} +#endif --- libstdc++-v3/testsuite/29_atomics/atomic_float/requirements_cxx23.cc.jj 2022-09-27 09:14:12.423997581 +0200 +++ libstdc++-v3/testsuite/29_atomics/atomic_float/requirements_cxx23.cc 2022-09-27 09:16:26.005195519 +0200 @@ -0,0 +1,112 @@ +// Copyright (C) 2022 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// { dg-options "-std=gnu++2b" } +// { dg-do compile { target c++23 } } + +#include <atomic> +#include <stdfloat> + +#if defined(__STDCPP_FLOAT16_T__) +void +test01() +{ + using A = std::atomic<std::float16_t>; + static_assert( std::is_standard_layout_v<A> ); + static_assert( !std::is_trivially_default_constructible_v<A> ); + static_assert( std::is_trivially_destructible_v<A> ); + static_assert( std::is_same_v<A::value_type, std::float16_t> ); + static_assert( std::is_same_v<A::difference_type, A::value_type> ); + static_assert( !std::is_copy_constructible_v<A> ); + static_assert( !std::is_move_constructible_v<A> ); + static_assert( !std::is_copy_assignable_v<A> ); + static_assert( !std::is_move_assignable_v<A> ); + static_assert( !std::is_assignable_v<volatile A&, const A&> ); +} +#endif + +#if defined(__STDCPP_FLOAT32_T__) +void +test02() +{ + using A = std::atomic<std::float32_t>; + static_assert( std::is_standard_layout_v<A> ); + static_assert( !std::is_trivially_default_constructible_v<A> ); + static_assert( std::is_trivially_destructible_v<A> ); + static_assert( std::is_same_v<A::value_type, std::float32_t> ); + static_assert( std::is_same_v<A::difference_type, A::value_type> ); + static_assert( !std::is_copy_constructible_v<A> ); + static_assert( !std::is_move_constructible_v<A> ); + static_assert( !std::is_copy_assignable_v<A> ); + static_assert( !std::is_move_assignable_v<A> ); + static_assert( !std::is_assignable_v<volatile A&, const A&> ); +} +#endif + +#if defined(__STDCPP_FLOAT64_T__) +void +test03() +{ + using A = std::atomic<std::float64_t>; + static_assert( std::is_standard_layout_v<A> ); + static_assert( !std::is_trivially_default_constructible_v<A> ); + static_assert( std::is_trivially_destructible_v<A> ); + static_assert( std::is_same_v<A::value_type, std::float64_t> ); + static_assert( std::is_same_v<A::difference_type, A::value_type> ); + static_assert( !std::is_copy_constructible_v<A> ); + static_assert( !std::is_move_constructible_v<A> ); + static_assert( !std::is_copy_assignable_v<A> ); + static_assert( !std::is_move_assignable_v<A> ); + static_assert( !std::is_assignable_v<volatile A&, const A&> ); +} +#endif + +#if defined(__STDCPP_FLOAT128_T__) +void +test04() +{ + using A = std::atomic<std::float128_t>; + static_assert( std::is_standard_layout_v<A> ); + static_assert( !std::is_trivially_default_constructible_v<A> ); + static_assert( std::is_trivially_destructible_v<A> ); + static_assert( std::is_same_v<A::value_type, std::float128_t> ); + static_assert( std::is_same_v<A::difference_type, A::value_type> ); + static_assert( !std::is_copy_constructible_v<A> ); + static_assert( !std::is_move_constructible_v<A> ); + static_assert( !std::is_copy_assignable_v<A> ); + static_assert( !std::is_move_assignable_v<A> ); + static_assert( !std::is_assignable_v<volatile A&, const A&> ); +} +#endif + +#if defined(__STDCPP_BFLOAT16_T__) +void +test05() +{ + using A = std::atomic<std::bfloat16_t>; + static_assert( std::is_standard_layout_v<A> ); + static_assert( !std::is_trivially_default_constructible_v<A> ); + static_assert( std::is_trivially_destructible_v<A> ); + static_assert( std::is_same_v<A::value_type, std::bfloat16_t> ); + static_assert( std::is_same_v<A::difference_type, A::value_type> ); + static_assert( !std::is_copy_constructible_v<A> ); + static_assert( !std::is_move_constructible_v<A> ); + static_assert( !std::is_copy_assignable_v<A> ); + static_assert( !std::is_move_assignable_v<A> ); + static_assert( !std::is_assignable_v<volatile A&, const A&> ); +} +#endif Jakub