Hi!
On Mon, Oct 17, 2022 at 02:07:00PM +0100, Jonathan Wakely wrote:
> Yes, that's now https://cplusplus.github.io/LWG/issue3790
> The current proposed resolution is to just restore the C++20 functions
> and not provide anything for the new types.
Ok.
> > If you want to have <cmath> done in a different way, e.g. the patch
> > groups a lot of different function overloads by the floating point type,
> > is that ok or do you want to have them one function at a time for all types,
> > then next?
>
> No, I think this way makes more sense. Otherwise the line count in the
> file will baloon with all the repeated #if #endif directives.
Ok, changed.
I've also changed this in limits and std_abs.h (ditto for
_GLIBCXX_USE_CONSTEXPR, _GLIBCXX_USE_NOEXCEPT).
There is one thing I'm not sure about but can be handled incrementally.
What exactly is is_iec559 supposed to be?
Currently for float/double/long double/__float128 it seems to be defined
to true if the type has Inf, qNaN and denormals.
For std::float{16,32,64,128}_t even a note in the spec says they are
true.
Shall it be true only if the type is actually a IEEE754 type
(binary16/32/64/128) and false otherwise, or that + the x86 extended type?
Or if it is IEEE754-like and shall it be true also for
std::bfloat16_t?
Yet another case is the IBM double double, which has infinities, NaNs
and denormals, but for that one it is hard to claim it is even IEEE754-like
(variable precision).
> > I could try to handle <complex> too, but am kind of lost there.
> > The paper dropped the explicit std::complex specializations, can they stay
> > around as is and should new overloads be added for the
> > _Float*/__gnu_cxx::__bfloat16_t types?
>
> The explicit specializations can stay, they do no harm.
Ok. Shall those specialization also get the P1467 changes for the ctors?
Shall we also have specializations for the extended floating point types,
or only conditionally (say when float is binary have _Complex _Float32
so that we get better code)?
> I can take care of the <complex> changes.
Ok.
> > And I/O etc. support is missing, not sure I'm able to handle that and if it
> > is e.g. possible to keep that support out of libstdc++.so.6, because what
> > extended floating point types one has on a particular arch could change over
> > time (I mean e.g. bfloat16_t support or float16_t support can be added
> > etc.).
>
> Yes, I think we can add the I/O functions as always_inline because all
> they're going to do is convert the argument to float, double, or long
> double and then call the existing overloads. There will be no new
> virtual functions.
>
> I can take care of that too.
Thanks.
Here is an updated patch that I'll test overnight (but can't commit
until the builtins patch is reviewed as it depends on that;
well, I could comment out the std::float128_t cmath support if
long double is not IEEE quad and commit that only once the builtins
patch is in).
2022-10-17 Jakub Jelinek <jakub@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} and __gnu_cxx::__bfloat16_t.
* include/std/atomic (atomic<_Float16>, atomic<_Float32>,
atomic<_Float64>, atomic<_Float128>, atomic<__gnu_cxx::__bfloat16_t>):
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>,
__is_floating_point_helper<__gnu_cxx::__bfloat16_t>): Likewise.
* include/std/limits (__glibcxx_concat3_, __glibcxx_concat3,
__glibcxx_float_n): Define.
(numeric_limits<_Float16>, numeric_limits<_Float32>,
numeric_limits<_Float64>, numeric_limits<_Float128>,
numeric_limits<__gnu_cxx::__bfloat16_t>): New explicit instantiations.
* include/bits/std_abs.h (abs): New overloads for
_Float{16,32,64,128} and __gnu_cxx::__bfloat16_t.
* include/bits/c++config (_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128): Define
if long double is IEEE quad.
(__gnu_cxx::__bfloat16_t): New using.
* include/c_global/cmath (acos, asin, atan, atan2, ceil, cos, cosh,
exp, fabs, floor, fmod, frexp, ldexp, log, log10, modf, pow, sin,
sinh, sqrt, tan, tanh, fpclassify, isfinite, isinf, isnan, isnormal,
signbit, isgreater, isgreaterequal, isless, islessequal,
islessgreater, isunordered, acosh, asinh, atanh, cbrt, copysign, erf,
erfc, exp2, expm1, fdim, fma, fmax, fmin, hypot, ilogb, lgamma,
llrint, llround, log1p, log2, logb, lrint, lround, nearbyint,
nextafter, remainder, rint, round, scalbln, scalbn, tgamma, trunc,
lerp): New overloads with _Float{16,32,64,128} or
__gnu_cxx::__bfloat16_t types.
* config/os/gnu-linux/os_defines.h (_GLIBCXX_HAVE_FLOAT128_MATH):
Define if glibc 2.26 and later implements *f128 APIs.
* include/ext/type_traits.h (__promote<_Float16>, __promote<_Float32>,
__promote<_Float64>, __promote<_Float128>,
__promote<__gnu_cxx::__bfloat16_t>): New specializations.
* 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/headers/cmath/c99_classification_macros_c++23.cc:
New test.
* testsuite/26_numerics/headers/cmath/functions_std_c++23.cc: New test.
* testsuite/26_numerics/numbers/4.cc: New test.
* testsuite/29_atomics/atomic_float/requirements_cxx23.cc: New test.
Jakub
@@ -0,0 +1,62 @@
+// <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
+
+ #ifdef __STDCPP_BFLOAT16_T__
+ using bfloat16_t = __gnu_cxx::__bfloat16_t;
+ #endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // C++23
+#endif // _GLIBCXX_STDFLOAT
@@ -133,72 +133,98 @@ 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
+
+#ifdef __STDCPP_BFLOAT128_T__
+__glibcxx_numbers (__gnu_cxx::__bfloat16_t, BF16);
+#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
@@ -1625,6 +1625,91 @@ _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
+
+#ifdef __STDCPP_BFLOAT16_T__
+ template<>
+ struct atomic<__gnu_cxx::__bfloat16_t> : __atomic_float<__gnu_cxx::__bfloat16_t>
+ {
+ atomic() noexcept = default;
+
+ constexpr
+ atomic(__gnu_cxx::__bfloat16_t __fp) noexcept : __atomic_float<__gnu_cxx::__bfloat16_t>(__fp)
+ { }
+
+ atomic& operator=(const atomic&) volatile = delete;
+ atomic& operator=(const atomic&) = delete;
+
+ using __atomic_float<__gnu_cxx::__bfloat16_t>::operator=;
+ };
+#endif
+
#define __cpp_lib_atomic_ref 201806L
/// Class template to provide atomic operations on a non-atomic variable.
@@ -459,6 +459,36 @@ _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
+
+#ifdef __STDCPP_BFLOAT16_T__
+ template<>
+ struct __is_floating_point_helper<__gnu_cxx::__bfloat16_t>
+ : public true_type { };
+#endif
+
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
template<>
struct __is_floating_point_helper<__float128>
@@ -1890,6 +1890,190 @@ _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 constexpr bool is_specialized = true; \
+ \
+ static constexpr _Float##BITSIZE \
+ min() noexcept \
+ { return __glibcxx_concat3 (__FLT, BITSIZE, _MIN__); } \
+ \
+ static constexpr _Float##BITSIZE \
+ max() noexcept \
+ { return __glibcxx_concat3 (__FLT, BITSIZE, _MAX__); } \
+ \
+ static constexpr _Float##BITSIZE \
+ lowest() noexcept \
+ { return -__glibcxx_concat3 (__FLT, BITSIZE, _MAX__); } \
+ \
+ static constexpr int digits \
+ = __glibcxx_concat3 (__FLT, BITSIZE, _MANT_DIG__); \
+ static constexpr int digits10 \
+ = __glibcxx_concat3 (__FLT, BITSIZE, _DIG__); \
+ static constexpr int max_digits10 \
+ = __glibcxx_max_digits10 (__glibcxx_concat3 (__FLT, BITSIZE, \
+ _MANT_DIG__)); \
+ static constexpr bool is_signed = true; \
+ static constexpr bool is_integer = false; \
+ static constexpr bool is_exact = false; \
+ static constexpr int radix \
+ = __glibcxx_concat3 (__FLT, BITSIZE, _RADIX__); \
+ \
+ static constexpr _Float##BITSIZE \
+ epsilon() noexcept \
+ { return __glibcxx_concat3 (__FLT, BITSIZE, _EPSILON__); } \
+ \
+ static constexpr _Float##BITSIZE \
+ round_error() noexcept { return 0.5F##BITSIZE; } \
+ \
+ static constexpr int min_exponent \
+ = __glibcxx_concat3 (__FLT, BITSIZE, _MIN_EXP__); \
+ static constexpr int min_exponent10 \
+ = __glibcxx_concat3 (__FLT, BITSIZE, _MIN_10_EXP__); \
+ static constexpr int max_exponent \
+ = __glibcxx_concat3 (__FLT, BITSIZE, _MAX_EXP__); \
+ static constexpr int max_exponent10 \
+ = __glibcxx_concat3 (__FLT, BITSIZE, _MAX_10_EXP__); \
+ \
+ static constexpr bool has_infinity \
+ = __glibcxx_concat3 (__FLT, BITSIZE, _HAS_INFINITY__); \
+ static constexpr bool has_quiet_NaN \
+ = __glibcxx_concat3 (__FLT, BITSIZE, _HAS_QUIET_NAN__); \
+ static constexpr bool has_signaling_NaN \
+ = has_quiet_NaN; \
+ static constexpr float_denorm_style has_denorm \
+ = bool(__glibcxx_concat3 (__FLT, BITSIZE, _HAS_DENORM__)) \
+ ? denorm_present : denorm_absent; \
+ static constexpr bool has_denorm_loss = false; \
+ \
+ static constexpr _Float##BITSIZE \
+ infinity() noexcept \
+ { return __builtin_huge_valf##BITSIZE(); } \
+ \
+ static constexpr _Float##BITSIZE \
+ quiet_NaN() noexcept \
+ { return __builtin_nanf##BITSIZE(""); } \
+ \
+ static constexpr _Float##BITSIZE \
+ signaling_NaN() noexcept \
+ { return __builtin_nansf##BITSIZE(""); } \
+ \
+ static constexpr _Float##BITSIZE \
+ denorm_min() noexcept \
+ { return __glibcxx_concat3 (__FLT, BITSIZE, _DENORM_MIN__); } \
+ \
+ static constexpr bool is_iec559 \
+ = has_infinity && has_quiet_NaN && has_denorm == denorm_present;\
+ static constexpr bool is_bounded = true; \
+ static constexpr bool is_modulo = false; \
+ \
+ static constexpr bool traps = false; \
+ static constexpr bool tinyness_before = false; \
+ static 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_
+
+#ifdef __STDCPP_BFLOAT16_T__
+ __extension__
+ template<>
+ struct numeric_limits<__gnu_cxx::__bfloat16_t>
+ {
+ static constexpr bool is_specialized = true;
+
+ static constexpr __gnu_cxx::__bfloat16_t
+ min() noexcept
+ { return __BFLT16_MIN__; }
+
+ static constexpr __gnu_cxx::__bfloat16_t
+ max() noexcept
+ { return __BFLT16_MAX__; }
+
+ static constexpr __gnu_cxx::__bfloat16_t
+ lowest() noexcept
+ { return -__BFLT16_MAX__; }
+
+ static constexpr int digits = __BFLT16_MANT_DIG__;
+ static constexpr int digits10 = __BFLT16_DIG__;
+ static constexpr int max_digits10
+ = __glibcxx_max_digits10 (__BFLT16_MANT_DIG__);
+ static constexpr bool is_signed = true;
+ static constexpr bool is_integer = false;
+ static constexpr bool is_exact = false;
+ static constexpr int radix = __BFLT16_RADIX__;
+
+ static constexpr __gnu_cxx::__bfloat16_t
+ epsilon() noexcept
+ { return __BFLT16_EPSILON__; }
+
+ static constexpr __gnu_cxx::__bfloat16_t
+ round_error() noexcept { return 0.5BF16; }
+
+ static constexpr int min_exponent = __BFLT16_MIN_EXP__;
+ static constexpr int min_exponent10 = __BFLT16_MIN_10_EXP__;
+ static constexpr int max_exponent = __BFLT16_MAX_EXP__;
+ static constexpr int max_exponent10 = __BFLT16_MAX_10_EXP__;
+
+ static constexpr bool has_infinity = __BFLT16_HAS_INFINITY__;
+ static constexpr bool has_quiet_NaN = __BFLT16_HAS_QUIET_NAN__;
+ static constexpr bool has_signaling_NaN = has_quiet_NaN;
+ static constexpr float_denorm_style has_denorm
+ = bool(__BFLT16_HAS_DENORM__)
+ ? denorm_present : denorm_absent;
+ static constexpr bool has_denorm_loss = false;
+
+ static constexpr __gnu_cxx::__bfloat16_t
+ infinity() noexcept
+ { return __gnu_cxx::__bfloat16_t(__builtin_huge_valf()); }
+
+ static constexpr __gnu_cxx::__bfloat16_t
+ quiet_NaN() noexcept
+ { return __gnu_cxx::__bfloat16_t(__builtin_nanf("")); }
+
+ static constexpr __gnu_cxx::__bfloat16_t
+ signaling_NaN() noexcept
+ { return __builtin_nansf16b(""); }
+
+ static constexpr __gnu_cxx::__bfloat16_t
+ denorm_min() noexcept
+ { return __BFLT16_DENORM_MIN__; }
+
+ static constexpr bool is_iec559
+ = has_infinity && has_quiet_NaN && has_denorm == denorm_present;
+ static constexpr bool is_bounded = true;
+ static constexpr bool is_modulo = false;
+
+ static constexpr bool traps = false;
+ static constexpr bool tinyness_before = false;
+ static constexpr float_round_style round_style = round_to_nearest;
+ };
+#endif
+
+#endif
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
@@ -97,6 +97,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
abs(__GLIBCXX_TYPE_INT_N_3 __x) { return __x >= 0 ? __x : -__x; }
#endif
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ constexpr _Float16
+ abs(_Float16 __x)
+ { return _Float16(__builtin_fabsf(__x)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ constexpr _Float32
+ abs(_Float32 __x)
+ { return __builtin_fabsf(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ constexpr _Float64
+ abs(_Float64 __x)
+ { return __builtin_fabs(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+ constexpr _Float128
+ abs(_Float128 __x)
+ { return __builtin_fabsl(__x); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+ constexpr _Float128
+ abs(_Float128 __x)
+ { return __builtin_fabsf128(__x); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ constexpr __gnu_cxx::__bfloat16_t
+ abs(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_fabsf(__x)); }
+#endif
+
#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_FLOAT128)
__extension__ inline _GLIBCXX_CONSTEXPR
__float128
@@ -796,6 +796,20 @@ namespace std
# define _GLIBCXX_DOUBLE_IS_IEEE_BINARY64 1
#endif
+// Define if long double has the IEEE binary128 format.
+#if __LDBL_MANT_DIG__ == 113 \
+ && __LDBL_MIN_EXP__ == -16381 \
+ && __LDBL_MAX_EXP__ == 16384
+# define _GLIBCXX_LDOUBLE_IS_IEEE_BINARY128 1
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+namespace __gnu_cxx
+{
+ using __bfloat16_t = decltype(0.0bf16);
+}
+#endif
+
#ifdef __has_builtin
# ifdef __is_identifier
// Intel and older Clang require !__is_identifier for some built-ins:
@@ -515,6 +515,564 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tanh(_Tp __x)
{ return __builtin_tanh(__x); }
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ constexpr _Float16
+ acos(_Float16 __x)
+ { return _Float16(__builtin_acosf(__x)); }
+
+ constexpr _Float16
+ asin(_Float16 __x)
+ { return _Float16(__builtin_asinf(__x)); }
+
+ constexpr _Float16
+ atan(_Float16 __x)
+ { return _Float16(__builtin_atanf(__x)); }
+
+ constexpr _Float16
+ atan2(_Float16 __y, _Float16 __x)
+ { return _Float16(__builtin_atan2f(__y, __x)); }
+
+ constexpr _Float16
+ ceil(_Float16 __x)
+ { return _Float16(__builtin_ceilf(__x)); }
+
+ constexpr _Float16
+ cos(_Float16 __x)
+ { return _Float16(__builtin_cosf(__x)); }
+
+ constexpr _Float16
+ cosh(_Float16 __x)
+ { return _Float16(__builtin_coshf(__x)); }
+
+ constexpr _Float16
+ exp(_Float16 __x)
+ { return _Float16(__builtin_expf(__x)); }
+
+ constexpr _Float16
+ fabs(_Float16 __x)
+ { return _Float16(__builtin_fabsf(__x)); }
+
+ constexpr _Float16
+ floor(_Float16 __x)
+ { return _Float16(__builtin_floorf(__x)); }
+
+ constexpr _Float16
+ fmod(_Float16 __x, _Float16 __y)
+ { return _Float16(__builtin_fmodf(__x, __y)); }
+
+ inline _Float16
+ frexp(_Float16 __x, int* __exp)
+ { return _Float16(__builtin_frexpf(__x, __exp)); }
+
+ constexpr _Float16
+ ldexp(_Float16 __x, int __exp)
+ { return _Float16(__builtin_ldexpf(__x, __exp)); }
+
+ constexpr _Float16
+ log(_Float16 __x)
+ { return _Float16(__builtin_logf(__x)); }
+
+ constexpr _Float16
+ log10(_Float16 __x)
+ { return _Float16(__builtin_log10f(__x)); }
+
+ inline _Float16
+ modf(_Float16 __x, _Float16* __iptr)
+ {
+ float __i, __ret = __builtin_modff(__x, &__i);
+ *__iptr = _Float16(__i);
+ return _Float16(__ret);
+ }
+
+ constexpr _Float16
+ pow(_Float16 __x, _Float16 __y)
+ { return _Float16(__builtin_powf(__x, __y)); }
+
+ constexpr _Float16
+ sin(_Float16 __x)
+ { return _Float16(__builtin_sinf(__x)); }
+
+ constexpr _Float16
+ sinh(_Float16 __x)
+ { return _Float16(__builtin_sinhf(__x)); }
+
+ constexpr _Float16
+ sqrt(_Float16 __x)
+ { return _Float16(__builtin_sqrtf(__x)); }
+
+ constexpr _Float16
+ tan(_Float16 __x)
+ { return _Float16(__builtin_tanf(__x)); }
+
+ constexpr _Float16
+ tanh(_Float16 __x)
+ { return _Float16(__builtin_tanhf(__x)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ constexpr _Float32
+ acos(_Float32 __x)
+ { return __builtin_acosf(__x); }
+
+ constexpr _Float32
+ asin(_Float32 __x)
+ { return __builtin_asinf(__x); }
+
+ constexpr _Float32
+ atan(_Float32 __x)
+ { return __builtin_atanf(__x); }
+
+ constexpr _Float32
+ atan2(_Float32 __y, _Float32 __x)
+ { return __builtin_atan2f(__y, __x); }
+
+ constexpr _Float32
+ ceil(_Float32 __x)
+ { return __builtin_ceilf(__x); }
+
+ constexpr _Float32
+ cos(_Float32 __x)
+ { return __builtin_cosf(__x); }
+
+ constexpr _Float32
+ cosh(_Float32 __x)
+ { return __builtin_coshf(__x); }
+
+ constexpr _Float32
+ exp(_Float32 __x)
+ { return __builtin_expf(__x); }
+
+ constexpr _Float32
+ fabs(_Float32 __x)
+ { return __builtin_fabsf(__x); }
+
+ constexpr _Float32
+ floor(_Float32 __x)
+ { return __builtin_floorf(__x); }
+
+ constexpr _Float32
+ fmod(_Float32 __x, _Float32 __y)
+ { return __builtin_fmodf(__x, __y); }
+
+ inline _Float32
+ frexp(_Float32 __x, int* __exp)
+ { return __builtin_frexpf(__x, __exp); }
+
+ constexpr _Float32
+ ldexp(_Float32 __x, int __exp)
+ { return __builtin_ldexpf(__x, __exp); }
+
+ constexpr _Float32
+ log(_Float32 __x)
+ { return __builtin_logf(__x); }
+
+ constexpr _Float32
+ log10(_Float32 __x)
+ { return __builtin_log10f(__x); }
+
+ inline _Float32
+ modf(_Float32 __x, _Float32* __iptr)
+ {
+ float __i, __ret = __builtin_modff(__x, &__i);
+ *__iptr = __i;
+ return __ret;
+ }
+
+ constexpr _Float32
+ pow(_Float32 __x, _Float32 __y)
+ { return __builtin_powf(__x, __y); }
+
+ constexpr _Float32
+ sin(_Float32 __x)
+ { return __builtin_sinf(__x); }
+
+ constexpr _Float32
+ sinh(_Float32 __x)
+ { return __builtin_sinhf(__x); }
+
+ constexpr _Float32
+ sqrt(_Float32 __x)
+ { return __builtin_sqrtf(__x); }
+
+ constexpr _Float32
+ tan(_Float32 __x)
+ { return __builtin_tanf(__x); }
+
+ constexpr _Float32
+ tanh(_Float32 __x)
+ { return __builtin_tanhf(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ constexpr _Float64
+ acos(_Float64 __x)
+ { return __builtin_acos(__x); }
+
+ constexpr _Float64
+ asin(_Float64 __x)
+ { return __builtin_asin(__x); }
+
+ constexpr _Float64
+ atan(_Float64 __x)
+ { return __builtin_atan(__x); }
+
+ constexpr _Float64
+ atan2(_Float64 __y, _Float64 __x)
+ { return __builtin_atan2(__y, __x); }
+
+ constexpr _Float64
+ ceil(_Float64 __x)
+ { return __builtin_ceil(__x); }
+
+ constexpr _Float64
+ cos(_Float64 __x)
+ { return __builtin_cos(__x); }
+
+ constexpr _Float64
+ cosh(_Float64 __x)
+ { return __builtin_cosh(__x); }
+
+ constexpr _Float64
+ exp(_Float64 __x)
+ { return __builtin_exp(__x); }
+
+ constexpr _Float64
+ fabs(_Float64 __x)
+ { return __builtin_fabs(__x); }
+
+ constexpr _Float64
+ floor(_Float64 __x)
+ { return __builtin_floor(__x); }
+
+ constexpr _Float64
+ fmod(_Float64 __x, _Float64 __y)
+ { return __builtin_fmod(__x, __y); }
+
+ inline _Float64
+ frexp(_Float64 __x, int* __exp)
+ { return __builtin_frexp(__x, __exp); }
+
+ constexpr _Float64
+ ldexp(_Float64 __x, int __exp)
+ { return __builtin_ldexp(__x, __exp); }
+
+ constexpr _Float64
+ log(_Float64 __x)
+ { return __builtin_log(__x); }
+
+ constexpr _Float64
+ log10(_Float64 __x)
+ { return __builtin_log10(__x); }
+
+ inline _Float64
+ modf(_Float64 __x, _Float64* __iptr)
+ {
+ double __i, __ret = __builtin_modf(__x, &__i);
+ *__iptr = __i;
+ return __ret;
+ }
+
+ constexpr _Float64
+ pow(_Float64 __x, _Float64 __y)
+ { return __builtin_pow(__x, __y); }
+
+ constexpr _Float64
+ sin(_Float64 __x)
+ { return __builtin_sin(__x); }
+
+ constexpr _Float64
+ sinh(_Float64 __x)
+ { return __builtin_sinh(__x); }
+
+ constexpr _Float64
+ sqrt(_Float64 __x)
+ { return __builtin_sqrt(__x); }
+
+ constexpr _Float64
+ tan(_Float64 __x)
+ { return __builtin_tan(__x); }
+
+ constexpr _Float64
+ tanh(_Float64 __x)
+ { return __builtin_tanh(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+ constexpr _Float128
+ acos(_Float128 __x)
+ { return __builtin_acosl(__x); }
+
+ constexpr _Float128
+ asin(_Float128 __x)
+ { return __builtin_asinl(__x); }
+
+ constexpr _Float128
+ atan(_Float128 __x)
+ { return __builtin_atanl(__x); }
+
+ constexpr _Float128
+ atan2(_Float128 __y, _Float128 __x)
+ { return __builtin_atan2l(__y, __x); }
+
+ constexpr _Float128
+ ceil(_Float128 __x)
+ { return __builtin_ceill(__x); }
+
+ constexpr _Float128
+ cos(_Float128 __x)
+ { return __builtin_cosl(__x); }
+
+ constexpr _Float128
+ cosh(_Float128 __x)
+ { return __builtin_coshl(__x); }
+
+ constexpr _Float128
+ exp(_Float128 __x)
+ { return __builtin_expl(__x); }
+
+ constexpr _Float128
+ fabs(_Float128 __x)
+ { return __builtin_fabsl(__x); }
+
+ constexpr _Float128
+ floor(_Float128 __x)
+ { return __builtin_floorl(__x); }
+
+ constexpr _Float128
+ fmod(_Float128 __x, _Float128 __y)
+ { return __builtin_fmodl(__x, __y); }
+
+ inline _Float128
+ frexp(_Float128 __x, int* __exp)
+ { return __builtin_frexpl(__x, __exp); }
+
+ constexpr _Float128
+ ldexp(_Float128 __x, int __exp)
+ { return __builtin_ldexpl(__x, __exp); }
+
+ constexpr _Float128
+ log(_Float128 __x)
+ { return __builtin_logl(__x); }
+
+ constexpr _Float128
+ log10(_Float128 __x)
+ { return __builtin_log10l(__x); }
+
+ inline _Float128
+ modf(_Float128 __x, _Float128* __iptr)
+ {
+ long double __i, __ret = __builtin_modfl(__x, &__i);
+ *__iptr = __i;
+ return __ret;
+ }
+
+ constexpr _Float128
+ pow(_Float128 __x, _Float128 __y)
+ { return __builtin_powl(__x, __y); }
+
+ constexpr _Float128
+ sin(_Float128 __x)
+ { return __builtin_sinl(__x); }
+
+ constexpr _Float128
+ sinh(_Float128 __x)
+ { return __builtin_sinhl(__x); }
+
+ constexpr _Float128
+ sqrt(_Float128 __x)
+ { return __builtin_sqrtl(__x); }
+
+ constexpr _Float128
+ tan(_Float128 __x)
+ { return __builtin_tanl(__x); }
+
+ constexpr _Float128
+ tanh(_Float128 __x)
+ { return __builtin_tanhl(__x); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+ constexpr _Float128
+ acos(_Float128 __x)
+ { return __builtin_acosf128(__x); }
+
+ constexpr _Float128
+ asin(_Float128 __x)
+ { return __builtin_asinf128(__x); }
+
+ constexpr _Float128
+ atan(_Float128 __x)
+ { return __builtin_atanf128(__x); }
+
+ constexpr _Float128
+ atan2(_Float128 __y, _Float128 __x)
+ { return __builtin_atan2f128(__y, __x); }
+
+ constexpr _Float128
+ ceil(_Float128 __x)
+ { return __builtin_ceilf128(__x); }
+
+ constexpr _Float128
+ cos(_Float128 __x)
+ { return __builtin_cosf128(__x); }
+
+ constexpr _Float128
+ cosh(_Float128 __x)
+ { return __builtin_coshf128(__x); }
+
+ constexpr _Float128
+ exp(_Float128 __x)
+ { return __builtin_expf128(__x); }
+
+ constexpr _Float128
+ fabs(_Float128 __x)
+ { return __builtin_fabsf128(__x); }
+
+ constexpr _Float128
+ floor(_Float128 __x)
+ { return __builtin_floorf128(__x); }
+
+ constexpr _Float128
+ fmod(_Float128 __x, _Float128 __y)
+ { return __builtin_fmodf128(__x, __y); }
+
+ inline _Float128
+ frexp(_Float128 __x, int* __exp)
+ { return __builtin_frexpf128(__x, __exp); }
+
+ constexpr _Float128
+ ldexp(_Float128 __x, int __exp)
+ { return __builtin_ldexpf128(__x, __exp); }
+
+ constexpr _Float128
+ log(_Float128 __x)
+ { return __builtin_logf128(__x); }
+
+ constexpr _Float128
+ log10(_Float128 __x)
+ { return __builtin_log10f128(__x); }
+
+ inline _Float128
+ modf(_Float128 __x, _Float128* __iptr)
+ { return __builtin_modff128(__x, __iptr); }
+
+ constexpr _Float128
+ pow(_Float128 __x, _Float128 __y)
+ { return __builtin_powf128(__x, __y); }
+
+ constexpr _Float128
+ sin(_Float128 __x)
+ { return __builtin_sinf128(__x); }
+
+ constexpr _Float128
+ sinh(_Float128 __x)
+ { return __builtin_sinhf128(__x); }
+
+ constexpr _Float128
+ sqrt(_Float128 __x)
+ { return __builtin_sqrtf128(__x); }
+
+ constexpr _Float128
+ tan(_Float128 __x)
+ { return __builtin_tanf128(__x); }
+
+ constexpr _Float128
+ tanh(_Float128 __x)
+ { return __builtin_tanhf128(__x); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ constexpr __gnu_cxx::__bfloat16_t
+ acos(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_acosf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ asin(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_asinf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ atan(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_atanf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ atan2(__gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_atan2f(__y, __x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ ceil(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_ceilf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ cos(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_cosf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ cosh(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_coshf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ exp(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_expf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ fabs(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_fabsf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ floor(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_floorf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ fmod(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __gnu_cxx::__bfloat16_t(__builtin_fmodf(__x, __y)); }
+
+ inline __gnu_cxx::__bfloat16_t
+ frexp(__gnu_cxx::__bfloat16_t __x, int* __exp)
+ { return __gnu_cxx::__bfloat16_t(__builtin_frexpf(__x, __exp)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ ldexp(__gnu_cxx::__bfloat16_t __x, int __exp)
+ { return __gnu_cxx::__bfloat16_t(__builtin_ldexpf(__x, __exp)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ log(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_logf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ log10(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_log10f(__x)); }
+
+ inline __gnu_cxx::__bfloat16_t
+ modf(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t* __iptr)
+ {
+ float __i, __ret = __builtin_modff(__x, &__i);
+ *__iptr = __gnu_cxx::__bfloat16_t(__i);
+ return __gnu_cxx::__bfloat16_t(__ret);
+ }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ pow(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __gnu_cxx::__bfloat16_t(__builtin_powf(__x, __y)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ sin(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_sinf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ sinh(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_sinhf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ sqrt(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_sqrtf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ tan(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_tanf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ tanh(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_tanhf(__x)); }
+#endif
+
#if _GLIBCXX_USE_C99_MATH
#if !_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC
@@ -948,6 +1506,262 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#endif // C++11
+
+#ifdef __STDCPP_FLOAT16_T__
+ constexpr int
+ fpclassify(_Float16 __x)
+ { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+ FP_SUBNORMAL, FP_ZERO, __x); }
+
+ constexpr bool
+ isfinite(_Float16 __x)
+ { return __builtin_isfinite(__x); }
+
+ constexpr bool
+ isinf(_Float16 __x)
+ { return __builtin_isinf(__x); }
+
+ constexpr bool
+ isnan(_Float16 __x)
+ { return __builtin_isnan(__x); }
+
+ constexpr bool
+ isnormal(_Float16 __x)
+ { return __builtin_isnormal(__x); }
+
+ constexpr bool
+ signbit(_Float16 __x)
+ { return __builtin_signbit(__x); }
+
+ constexpr bool
+ isgreater(_Float16 __x, _Float16 __y)
+ { return __builtin_isgreater(__x, __y); }
+
+ constexpr bool
+ isgreaterequal(_Float16 __x, _Float16 __y)
+ { return __builtin_isgreaterequal(__x, __y); }
+
+ constexpr bool
+ isless(_Float16 __x, _Float16 __y)
+ { return __builtin_isless(__x, __y); }
+
+ constexpr bool
+ islessequal(_Float16 __x, _Float16 __y)
+ { return __builtin_islessequal(__x, __y); }
+
+ constexpr bool
+ islessgreater(_Float16 __x, _Float16 __y)
+ { return __builtin_islessgreater(__x, __y); }
+
+ constexpr bool
+ isunordered(_Float16 __x, _Float16 __y)
+ { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+ constexpr int
+ fpclassify(_Float32 __x)
+ { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+ FP_SUBNORMAL, FP_ZERO, __x); }
+
+ constexpr bool
+ isfinite(_Float32 __x)
+ { return __builtin_isfinite(__x); }
+
+ constexpr bool
+ isinf(_Float32 __x)
+ { return __builtin_isinf(__x); }
+
+ constexpr bool
+ isnan(_Float32 __x)
+ { return __builtin_isnan(__x); }
+
+ constexpr bool
+ isnormal(_Float32 __x)
+ { return __builtin_isnormal(__x); }
+
+ constexpr bool
+ signbit(_Float32 __x)
+ { return __builtin_signbit(__x); }
+
+ constexpr bool
+ isgreater(_Float32 __x, _Float32 __y)
+ { return __builtin_isgreater(__x, __y); }
+
+ constexpr bool
+ isgreaterequal(_Float32 __x, _Float32 __y)
+ { return __builtin_isgreaterequal(__x, __y); }
+
+ constexpr bool
+ isless(_Float32 __x, _Float32 __y)
+ { return __builtin_isless(__x, __y); }
+
+ constexpr bool
+ islessequal(_Float32 __x, _Float32 __y)
+ { return __builtin_islessequal(__x, __y); }
+
+ constexpr bool
+ islessgreater(_Float32 __x, _Float32 __y)
+ { return __builtin_islessgreater(__x, __y); }
+
+ constexpr bool
+ isunordered(_Float32 __x, _Float32 __y)
+ { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+ constexpr int
+ fpclassify(_Float64 __x)
+ { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+ FP_SUBNORMAL, FP_ZERO, __x); }
+
+ constexpr bool
+ isfinite(_Float64 __x)
+ { return __builtin_isfinite(__x); }
+
+ constexpr bool
+ isinf(_Float64 __x)
+ { return __builtin_isinf(__x); }
+
+ constexpr bool
+ isnan(_Float64 __x)
+ { return __builtin_isnan(__x); }
+
+ constexpr bool
+ isnormal(_Float64 __x)
+ { return __builtin_isnormal(__x); }
+
+ constexpr bool
+ signbit(_Float64 __x)
+ { return __builtin_signbit(__x); }
+
+ constexpr bool
+ isgreater(_Float64 __x, _Float64 __y)
+ { return __builtin_isgreater(__x, __y); }
+
+ constexpr bool
+ isgreaterequal(_Float64 __x, _Float64 __y)
+ { return __builtin_isgreaterequal(__x, __y); }
+
+ constexpr bool
+ isless(_Float64 __x, _Float64 __y)
+ { return __builtin_isless(__x, __y); }
+
+ constexpr bool
+ islessequal(_Float64 __x, _Float64 __y)
+ { return __builtin_islessequal(__x, __y); }
+
+ constexpr bool
+ islessgreater(_Float64 __x, _Float64 __y)
+ { return __builtin_islessgreater(__x, __y); }
+
+ constexpr bool
+ isunordered(_Float64 __x, _Float64 __y)
+ { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+ constexpr int
+ fpclassify(_Float128 __x)
+ { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+ FP_SUBNORMAL, FP_ZERO, __x); }
+
+ constexpr bool
+ isfinite(_Float128 __x)
+ { return __builtin_isfinite(__x); }
+
+ constexpr bool
+ isinf(_Float128 __x)
+ { return __builtin_isinf(__x); }
+
+ constexpr bool
+ isnan(_Float128 __x)
+ { return __builtin_isnan(__x); }
+
+ constexpr bool
+ isnormal(_Float128 __x)
+ { return __builtin_isnormal(__x); }
+
+ constexpr bool
+ signbit(_Float128 __x)
+ { return __builtin_signbit(__x); }
+
+ constexpr bool
+ isgreater(_Float128 __x, _Float128 __y)
+ { return __builtin_isgreater(__x, __y); }
+
+ constexpr bool
+ isgreaterequal(_Float128 __x, _Float128 __y)
+ { return __builtin_isgreaterequal(__x, __y); }
+
+ constexpr bool
+ isless(_Float128 __x, _Float128 __y)
+ { return __builtin_isless(__x, __y); }
+
+ constexpr bool
+ islessequal(_Float128 __x, _Float128 __y)
+ { return __builtin_islessequal(__x, __y); }
+
+ constexpr bool
+ islessgreater(_Float128 __x, _Float128 __y)
+ { return __builtin_islessgreater(__x, __y); }
+
+ constexpr bool
+ isunordered(_Float128 __x, _Float128 __y)
+ { return __builtin_isunordered(__x, __y); }
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+ constexpr int
+ fpclassify(__gnu_cxx::__bfloat16_t __x)
+ { return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL,
+ FP_SUBNORMAL, FP_ZERO, __x); }
+
+ constexpr bool
+ isfinite(__gnu_cxx::__bfloat16_t __x)
+ { return __builtin_isfinite(__x); }
+
+ constexpr bool
+ isinf(__gnu_cxx::__bfloat16_t __x)
+ { return __builtin_isinf(__x); }
+
+ constexpr bool
+ isnan(__gnu_cxx::__bfloat16_t __x)
+ { return __builtin_isnan(__x); }
+
+ constexpr bool
+ isnormal(__gnu_cxx::__bfloat16_t __x)
+ { return __builtin_isnormal(__x); }
+
+ constexpr bool
+ signbit(__gnu_cxx::__bfloat16_t __x)
+ { return __builtin_signbit(__x); }
+
+ constexpr bool
+ isgreater(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __builtin_isgreater(__x, __y); }
+
+ constexpr bool
+ isgreaterequal(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __builtin_isgreaterequal(__x, __y); }
+
+ constexpr bool
+ isless(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __builtin_isless(__x, __y); }
+
+ constexpr bool
+ islessequal(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __builtin_islessequal(__x, __y); }
+
+ constexpr bool
+ islessgreater(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __builtin_islessgreater(__x, __y); }
+
+ constexpr bool
+ isunordered(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __builtin_isunordered(__x, __y); }
+#endif
+
#endif /* _GLIBCXX_USE_C99_FP_MACROS_DYNAMIC */
#endif /* _GLIBCXX_USE_C99_MATH */
@@ -1843,6 +2657,811 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return __builtin_trunc(__x); }
#endif
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ constexpr _Float16
+ acosh(_Float16 __x)
+ { return _Float16(__builtin_acoshf(__x)); }
+
+ constexpr _Float16
+ asinh(_Float16 __x)
+ { return _Float16(__builtin_asinhf(__x)); }
+
+ constexpr _Float16
+ atanh(_Float16 __x)
+ { return _Float16(__builtin_atanhf(__x)); }
+
+ constexpr _Float16
+ cbrt(_Float16 __x)
+ { return _Float16(__builtin_cbrtf(__x)); }
+
+ constexpr _Float16
+ copysign(_Float16 __x, _Float16 __y)
+ { return __builtin_copysignf16(__x, __y); }
+
+ constexpr _Float16
+ erf(_Float16 __x)
+ { return _Float16(__builtin_erff(__x)); }
+
+ constexpr _Float16
+ erfc(_Float16 __x)
+ { return _Float16(__builtin_erfcf(__x)); }
+
+ constexpr _Float16
+ exp2(_Float16 __x)
+ { return _Float16(__builtin_exp2f(__x)); }
+
+ constexpr _Float16
+ expm1(_Float16 __x)
+ { return _Float16(__builtin_expm1f(__x)); }
+
+ constexpr _Float16
+ fdim(_Float16 __x, _Float16 __y)
+ { return _Float16(__builtin_fdimf(__x, __y)); }
+
+ constexpr _Float16
+ fma(_Float16 __x, _Float16 __y, _Float16 __z)
+ { return _Float16(__builtin_fmaf(__x, __y, __z)); }
+
+ constexpr _Float16
+ fmax(_Float16 __x, _Float16 __y)
+ { return _Float16(__builtin_fmaxf(__x, __y)); }
+
+ constexpr _Float16
+ fmin(_Float16 __x, _Float16 __y)
+ { return _Float16(__builtin_fminf(__x, __y)); }
+
+ constexpr _Float16
+ hypot(_Float16 __x, _Float16 __y)
+ { return _Float16(__builtin_hypotf(__x, __y)); }
+
+ constexpr int
+ ilogb(_Float16 __x)
+ { return _Float16(__builtin_ilogbf(__x)); }
+
+ constexpr _Float16
+ lgamma(_Float16 __x)
+ { return _Float16(__builtin_lgammaf(__x)); }
+
+ constexpr long long
+ llrint(_Float16 __x)
+ { return _Float16(__builtin_llrintf(__x)); }
+
+ constexpr long long
+ llround(_Float16 __x)
+ { return _Float16(__builtin_llroundf(__x)); }
+
+ constexpr _Float16
+ log1p(_Float16 __x)
+ { return _Float16(__builtin_log1pf(__x)); }
+
+ // DR 568.
+ constexpr _Float16
+ log2(_Float16 __x)
+ { return _Float16(__builtin_log2f(__x)); }
+
+ constexpr _Float16
+ logb(_Float16 __x)
+ { return _Float16(__builtin_logbf(__x)); }
+
+ constexpr long
+ lrint(_Float16 __x)
+ { return _Float16(__builtin_lrintf(__x)); }
+
+ constexpr long
+ lround(_Float16 __x)
+ { return _Float16(__builtin_lroundf(__x)); }
+
+ constexpr _Float16
+ nearbyint(_Float16 __x)
+ { return _Float16(__builtin_nearbyintf(__x)); }
+
+ // nextafter not implemented so far.
+
+ constexpr _Float16
+ remainder(_Float16 __x, _Float16 __y)
+ { return _Float16(__builtin_remainderf(__x, __y)); }
+
+ inline _Float16
+ remquo(_Float16 __x, _Float16 __y, int* __pquo)
+ { return _Float16(__builtin_remquof(__x, __y, __pquo)); }
+
+ constexpr _Float16
+ rint(_Float16 __x)
+ { return _Float16(__builtin_rintf(__x)); }
+
+ constexpr _Float16
+ round(_Float16 __x)
+ { return _Float16(__builtin_roundf(__x)); }
+
+ constexpr _Float16
+ scalbln(_Float16 __x, long __ex)
+ { return _Float16(__builtin_scalblnf(__x, __ex)); }
+
+ constexpr _Float16
+ scalbn(_Float16 __x, int __ex)
+ { return _Float16(__builtin_scalbnf(__x, __ex)); }
+
+ constexpr _Float16
+ tgamma(_Float16 __x)
+ { return _Float16(__builtin_tgammaf(__x)); }
+
+ constexpr _Float16
+ trunc(_Float16 __x)
+ { return _Float16(__builtin_truncf(__x)); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ constexpr _Float32
+ acosh(_Float32 __x)
+ { return __builtin_acoshf(__x); }
+
+ constexpr _Float32
+ asinh(_Float32 __x)
+ { return __builtin_asinhf(__x); }
+
+ constexpr _Float32
+ atanh(_Float32 __x)
+ { return __builtin_atanhf(__x); }
+
+ constexpr _Float32
+ cbrt(_Float32 __x)
+ { return __builtin_cbrtf(__x); }
+
+ constexpr _Float32
+ copysign(_Float32 __x, _Float32 __y)
+ { return __builtin_copysignf(__x, __y); }
+
+ constexpr _Float32
+ erf(_Float32 __x)
+ { return __builtin_erff(__x); }
+
+ constexpr _Float32
+ erfc(_Float32 __x)
+ { return __builtin_erfcf(__x); }
+
+ constexpr _Float32
+ exp2(_Float32 __x)
+ { return __builtin_exp2f(__x); }
+
+ constexpr _Float32
+ expm1(_Float32 __x)
+ { return __builtin_expm1f(__x); }
+
+ constexpr _Float32
+ fdim(_Float32 __x, _Float32 __y)
+ { return __builtin_fdimf(__x, __y); }
+
+ constexpr _Float32
+ fma(_Float32 __x, _Float32 __y, _Float32 __z)
+ { return __builtin_fmaf(__x, __y, __z); }
+
+ constexpr _Float32
+ fmax(_Float32 __x, _Float32 __y)
+ { return __builtin_fmaxf(__x, __y); }
+
+ constexpr _Float32
+ fmin(_Float32 __x, _Float32 __y)
+ { return __builtin_fminf(__x, __y); }
+
+ constexpr _Float32
+ hypot(_Float32 __x, _Float32 __y)
+ { return __builtin_hypotf(__x, __y); }
+
+ constexpr int
+ ilogb(_Float32 __x)
+ { return __builtin_ilogbf(__x); }
+
+ constexpr _Float32
+ lgamma(_Float32 __x)
+ { return __builtin_lgammaf(__x); }
+
+ constexpr long long
+ llrint(_Float32 __x)
+ { return __builtin_llrintf(__x); }
+
+ constexpr long long
+ llround(_Float32 __x)
+ { return __builtin_llroundf(__x); }
+
+ constexpr _Float32
+ log1p(_Float32 __x)
+ { return __builtin_log1pf(__x); }
+
+ // DR 568.
+ constexpr _Float32
+ log2(_Float32 __x)
+ { return __builtin_log2f(__x); }
+
+ constexpr _Float32
+ logb(_Float32 __x)
+ { return __builtin_logbf(__x); }
+
+ constexpr long
+ lrint(_Float32 __x)
+ { return __builtin_lrintf(__x); }
+
+ constexpr long
+ lround(_Float32 __x)
+ { return __builtin_lroundf(__x); }
+
+ constexpr _Float32
+ nearbyint(_Float32 __x)
+ { return __builtin_nearbyintf(__x); }
+
+ constexpr _Float32
+ nextafter(_Float32 __x, _Float32 __y)
+ { return __builtin_nextafterf(__x, __y); }
+
+ constexpr _Float32
+ remainder(_Float32 __x, _Float32 __y)
+ { return __builtin_remainderf(__x, __y); }
+
+ inline _Float32
+ remquo(_Float32 __x, _Float32 __y, int* __pquo)
+ { return __builtin_remquof(__x, __y, __pquo); }
+
+ constexpr _Float32
+ rint(_Float32 __x)
+ { return __builtin_rintf(__x); }
+
+ constexpr _Float32
+ round(_Float32 __x)
+ { return __builtin_roundf(__x); }
+
+ constexpr _Float32
+ scalbln(_Float32 __x, long __ex)
+ { return __builtin_scalblnf(__x, __ex); }
+
+ constexpr _Float32
+ scalbn(_Float32 __x, int __ex)
+ { return __builtin_scalbnf(__x, __ex); }
+
+ constexpr _Float32
+ tgamma(_Float32 __x)
+ { return __builtin_tgammaf(__x); }
+
+ constexpr _Float32
+ trunc(_Float32 __x)
+ { return __builtin_truncf(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ constexpr _Float64
+ acosh(_Float64 __x)
+ { return __builtin_acosh(__x); }
+
+ constexpr _Float64
+ asinh(_Float64 __x)
+ { return __builtin_asinh(__x); }
+
+ constexpr _Float64
+ atanh(_Float64 __x)
+ { return __builtin_atanh(__x); }
+
+ constexpr _Float64
+ cbrt(_Float64 __x)
+ { return __builtin_cbrt(__x); }
+
+ constexpr _Float64
+ copysign(_Float64 __x, _Float64 __y)
+ { return __builtin_copysign(__x, __y); }
+
+ constexpr _Float64
+ erf(_Float64 __x)
+ { return __builtin_erf(__x); }
+
+ constexpr _Float64
+ erfc(_Float64 __x)
+ { return __builtin_erfc(__x); }
+
+ constexpr _Float64
+ exp2(_Float64 __x)
+ { return __builtin_exp2(__x); }
+
+ constexpr _Float64
+ expm1(_Float64 __x)
+ { return __builtin_expm1(__x); }
+
+ constexpr _Float64
+ fdim(_Float64 __x, _Float64 __y)
+ { return __builtin_fdim(__x, __y); }
+
+ constexpr _Float64
+ fma(_Float64 __x, _Float64 __y, _Float64 __z)
+ { return __builtin_fma(__x, __y, __z); }
+
+ constexpr _Float64
+ fmax(_Float64 __x, _Float64 __y)
+ { return __builtin_fmax(__x, __y); }
+
+ constexpr _Float64
+ fmin(_Float64 __x, _Float64 __y)
+ { return __builtin_fmin(__x, __y); }
+
+ constexpr _Float64
+ hypot(_Float64 __x, _Float64 __y)
+ { return __builtin_hypot(__x, __y); }
+
+ constexpr int
+ ilogb(_Float64 __x)
+ { return __builtin_ilogb(__x); }
+
+ constexpr _Float64
+ lgamma(_Float64 __x)
+ { return __builtin_lgamma(__x); }
+
+ constexpr long long
+ llrint(_Float64 __x)
+ { return __builtin_llrint(__x); }
+
+ constexpr long long
+ llround(_Float64 __x)
+ { return __builtin_llround(__x); }
+
+ constexpr _Float64
+ log1p(_Float64 __x)
+ { return __builtin_log1p(__x); }
+
+ // DR 568.
+ constexpr _Float64
+ log2(_Float64 __x)
+ { return __builtin_log2(__x); }
+
+ constexpr _Float64
+ logb(_Float64 __x)
+ { return __builtin_logb(__x); }
+
+ constexpr long
+ lrint(_Float64 __x)
+ { return __builtin_lrint(__x); }
+
+ constexpr long
+ lround(_Float64 __x)
+ { return __builtin_lround(__x); }
+
+ constexpr _Float64
+ nearbyint(_Float64 __x)
+ { return __builtin_nearbyint(__x); }
+
+ constexpr _Float64
+ nextafter(_Float64 __x, _Float64 __y)
+ { return __builtin_nextafter(__x, __y); }
+
+ constexpr _Float64
+ remainder(_Float64 __x, _Float64 __y)
+ { return __builtin_remainder(__x, __y); }
+
+ inline _Float64
+ remquo(_Float64 __x, _Float64 __y, int* __pquo)
+ { return __builtin_remquo(__x, __y, __pquo); }
+
+ constexpr _Float64
+ rint(_Float64 __x)
+ { return __builtin_rint(__x); }
+
+ constexpr _Float64
+ round(_Float64 __x)
+ { return __builtin_round(__x); }
+
+ constexpr _Float64
+ scalbln(_Float64 __x, long __ex)
+ { return __builtin_scalbln(__x, __ex); }
+
+ constexpr _Float64
+ scalbn(_Float64 __x, int __ex)
+ { return __builtin_scalbn(__x, __ex); }
+
+ constexpr _Float64
+ tgamma(_Float64 __x)
+ { return __builtin_tgamma(__x); }
+
+ constexpr _Float64
+ trunc(_Float64 __x)
+ { return __builtin_trunc(__x); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+ constexpr _Float128
+ acosh(_Float128 __x)
+ { return __builtin_acoshl(__x); }
+
+ constexpr _Float128
+ asinh(_Float128 __x)
+ { return __builtin_asinhl(__x); }
+
+ constexpr _Float128
+ atanh(_Float128 __x)
+ { return __builtin_atanhl(__x); }
+
+ constexpr _Float128
+ cbrt(_Float128 __x)
+ { return __builtin_cbrtl(__x); }
+
+ constexpr _Float128
+ copysign(_Float128 __x, _Float128 __y)
+ { return __builtin_copysignl(__x, __y); }
+
+ constexpr _Float128
+ erf(_Float128 __x)
+ { return __builtin_erfl(__x); }
+
+ constexpr _Float128
+ erfc(_Float128 __x)
+ { return __builtin_erfcl(__x); }
+
+ constexpr _Float128
+ exp2(_Float128 __x)
+ { return __builtin_exp2l(__x); }
+
+ constexpr _Float128
+ expm1(_Float128 __x)
+ { return __builtin_expm1l(__x); }
+
+ constexpr _Float128
+ fdim(_Float128 __x, _Float128 __y)
+ { return __builtin_fdiml(__x, __y); }
+
+ constexpr _Float128
+ fma(_Float128 __x, _Float128 __y, _Float128 __z)
+ { return __builtin_fmal(__x, __y, __z); }
+
+ constexpr _Float128
+ fmax(_Float128 __x, _Float128 __y)
+ { return __builtin_fmaxl(__x, __y); }
+
+ constexpr _Float128
+ fmin(_Float128 __x, _Float128 __y)
+ { return __builtin_fminl(__x, __y); }
+
+ constexpr _Float128
+ hypot(_Float128 __x, _Float128 __y)
+ { return __builtin_hypotl(__x, __y); }
+
+ constexpr int
+ ilogb(_Float128 __x)
+ { return __builtin_ilogbl(__x); }
+
+ constexpr _Float128
+ lgamma(_Float128 __x)
+ { return __builtin_lgammal(__x); }
+
+ constexpr long long
+ llrint(_Float128 __x)
+ { return __builtin_llrintl(__x); }
+
+ constexpr long long
+ llround(_Float128 __x)
+ { return __builtin_llroundl(__x); }
+
+ constexpr _Float128
+ log1p(_Float128 __x)
+ { return __builtin_log1pl(__x); }
+
+ // DR 568.
+ constexpr _Float128
+ log2(_Float128 __x)
+ { return __builtin_log2l(__x); }
+
+ constexpr _Float128
+ logb(_Float128 __x)
+ { return __builtin_logbl(__x); }
+
+ constexpr long
+ lrint(_Float128 __x)
+ { return __builtin_lrintl(__x); }
+
+ constexpr long
+ lround(_Float128 __x)
+ { return __builtin_lroundl(__x); }
+
+ constexpr _Float128
+ nearbyint(_Float128 __x)
+ { return __builtin_nearbyintl(__x); }
+
+ constexpr _Float128
+ nextafter(_Float128 __x, _Float128 __y)
+ { return __builtin_nextafterl(__x, __y); }
+
+ constexpr _Float128
+ remainder(_Float128 __x, _Float128 __y)
+ { return __builtin_remainderl(__x, __y); }
+
+ inline _Float128
+ remquo(_Float128 __x, _Float128 __y, int* __pquo)
+ { return __builtin_remquol(__x, __y, __pquo); }
+
+ constexpr _Float128
+ rint(_Float128 __x)
+ { return __builtin_rintl(__x); }
+
+ constexpr _Float128
+ round(_Float128 __x)
+ { return __builtin_roundl(__x); }
+
+ constexpr _Float128
+ scalbln(_Float128 __x, long __ex)
+ { return __builtin_scalblnl(__x, __ex); }
+
+ constexpr _Float128
+ scalbn(_Float128 __x, int __ex)
+ { return __builtin_scalbnl(__x, __ex); }
+
+ constexpr _Float128
+ tgamma(_Float128 __x)
+ { return __builtin_tgammal(__x); }
+
+ constexpr _Float128
+ trunc(_Float128 __x)
+ { return __builtin_truncl(__x); }
+#elif defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_HAVE_FLOAT128_MATH)
+ constexpr _Float128
+ acosh(_Float128 __x)
+ { return __builtin_acoshf128(__x); }
+
+ constexpr _Float128
+ asinh(_Float128 __x)
+ { return __builtin_asinhf128(__x); }
+
+ constexpr _Float128
+ atanh(_Float128 __x)
+ { return __builtin_atanhf128(__x); }
+
+ constexpr _Float128
+ cbrt(_Float128 __x)
+ { return __builtin_cbrtf128(__x); }
+
+ constexpr _Float128
+ copysign(_Float128 __x, _Float128 __y)
+ { return __builtin_copysignf128(__x, __y); }
+
+ constexpr _Float128
+ erf(_Float128 __x)
+ { return __builtin_erff128(__x); }
+
+ constexpr _Float128
+ erfc(_Float128 __x)
+ { return __builtin_erfcf128(__x); }
+
+ constexpr _Float128
+ exp2(_Float128 __x)
+ { return __builtin_exp2f128(__x); }
+
+ constexpr _Float128
+ expm1(_Float128 __x)
+ { return __builtin_expm1f128(__x); }
+
+ constexpr _Float128
+ fdim(_Float128 __x, _Float128 __y)
+ { return __builtin_fdimf128(__x, __y); }
+
+ constexpr _Float128
+ fma(_Float128 __x, _Float128 __y, _Float128 __z)
+ { return __builtin_fmaf128(__x, __y, __z); }
+
+ constexpr _Float128
+ fmax(_Float128 __x, _Float128 __y)
+ { return __builtin_fmaxf128(__x, __y); }
+
+ constexpr _Float128
+ fmin(_Float128 __x, _Float128 __y)
+ { return __builtin_fminf128(__x, __y); }
+
+ constexpr _Float128
+ hypot(_Float128 __x, _Float128 __y)
+ { return __builtin_hypotf128(__x, __y); }
+
+ constexpr int
+ ilogb(_Float128 __x)
+ { return __builtin_ilogbf128(__x); }
+
+ constexpr _Float128
+ lgamma(_Float128 __x)
+ { return __builtin_lgammaf128(__x); }
+
+ constexpr long long
+ llrint(_Float128 __x)
+ { return __builtin_llrintf128(__x); }
+
+ constexpr long long
+ llround(_Float128 __x)
+ { return __builtin_llroundf128(__x); }
+
+ constexpr _Float128
+ log1p(_Float128 __x)
+ { return __builtin_log1pf128(__x); }
+
+ // DR 568.
+ constexpr _Float128
+ log2(_Float128 __x)
+ { return __builtin_log2f128(__x); }
+
+ constexpr _Float128
+ logb(_Float128 __x)
+ { return __builtin_logbf128(__x); }
+
+ constexpr long
+ lrint(_Float128 __x)
+ { return __builtin_lrintf128(__x); }
+
+ constexpr long
+ lround(_Float128 __x)
+ { return __builtin_lroundf128(__x); }
+
+ constexpr _Float128
+ nearbyint(_Float128 __x)
+ { return __builtin_nearbyintf128(__x); }
+
+ constexpr _Float128
+ nextafter(_Float128 __x, _Float128 __y)
+ { return __builtin_nextafterf128(__x, __y); }
+
+ constexpr _Float128
+ remainder(_Float128 __x, _Float128 __y)
+ { return __builtin_remainderf128(__x, __y); }
+
+ inline _Float128
+ remquo(_Float128 __x, _Float128 __y, int* __pquo)
+ { return __builtin_remquof128(__x, __y, __pquo); }
+
+ constexpr _Float128
+ rint(_Float128 __x)
+ { return __builtin_rintf128(__x); }
+
+ constexpr _Float128
+ round(_Float128 __x)
+ { return __builtin_roundf128(__x); }
+
+ constexpr _Float128
+ scalbln(_Float128 __x, long __ex)
+ { return __builtin_scalblnf128(__x, __ex); }
+
+ constexpr _Float128
+ scalbn(_Float128 __x, int __ex)
+ { return __builtin_scalbnf128(__x, __ex); }
+
+ constexpr _Float128
+ tgamma(_Float128 __x)
+ { return __builtin_tgammaf128(__x); }
+
+ constexpr _Float128
+ trunc(_Float128 __x)
+ { return __builtin_truncf128(__x); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ constexpr __gnu_cxx::__bfloat16_t
+ acosh(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_acoshf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ asinh(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_asinhf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ atanh(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_atanhf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ cbrt(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_cbrtf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ copysign(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __gnu_cxx::__bfloat16_t(__builtin_copysignf(__x, __y)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ erf(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_erff(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ erfc(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_erfcf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ exp2(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_exp2f(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ expm1(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_expm1f(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ fdim(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __gnu_cxx::__bfloat16_t(__builtin_fdimf(__x, __y)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ fma(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __z)
+ { return __gnu_cxx::__bfloat16_t(__builtin_fmaf(__x, __y, __z)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ fmax(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __gnu_cxx::__bfloat16_t(__builtin_fmaxf(__x, __y)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ fmin(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __gnu_cxx::__bfloat16_t(__builtin_fminf(__x, __y)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ hypot(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __gnu_cxx::__bfloat16_t(__builtin_hypotf(__x, __y)); }
+
+ constexpr int
+ ilogb(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_ilogbf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ lgamma(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_lgammaf(__x)); }
+
+ constexpr long long
+ llrint(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_llrintf(__x)); }
+
+ constexpr long long
+ llround(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_llroundf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ log1p(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_log1pf(__x)); }
+
+ // DR 568.
+ constexpr __gnu_cxx::__bfloat16_t
+ log2(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_log2f(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ logb(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_logbf(__x)); }
+
+ constexpr long
+ lrint(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_lrintf(__x)); }
+
+ constexpr long
+ lround(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_lroundf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ nearbyint(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_nearbyintf(__x)); }
+
+ // nextafter not implemented so far.
+
+ constexpr __gnu_cxx::__bfloat16_t
+ remainder(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y)
+ { return __gnu_cxx::__bfloat16_t(__builtin_remainderf(__x, __y)); }
+
+ inline __gnu_cxx::__bfloat16_t
+ remquo(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, int* __pquo)
+ { return __gnu_cxx::__bfloat16_t(__builtin_remquof(__x, __y, __pquo)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ rint(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_rintf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ round(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_roundf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ scalbln(__gnu_cxx::__bfloat16_t __x, long __ex)
+ { return __gnu_cxx::__bfloat16_t(__builtin_scalblnf(__x, __ex)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ scalbn(__gnu_cxx::__bfloat16_t __x, int __ex)
+ { return __gnu_cxx::__bfloat16_t(__builtin_scalbnf(__x, __ex)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ tgamma(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_tgammaf(__x)); }
+
+ constexpr __gnu_cxx::__bfloat16_t
+ trunc(__gnu_cxx::__bfloat16_t __x)
+ { return __gnu_cxx::__bfloat16_t(__builtin_truncf(__x)); }
+#endif
+
+
#endif // _GLIBCXX_USE_C99_MATH_TR1
#endif // C++11
@@ -1885,6 +3504,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __type = __gnu_cxx::__promoted_t<_Tp, _Up, _Vp>;
return std::__hypot3<__type>(__x, __y, __z);
}
+
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ inline _Float16
+ hypot(_Float16 __x, _Float16 __y, _Float16 __z)
+ { return std::__hypot3<_Float16>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ inline _Float32
+ hypot(_Float32 __x, _Float32 __y, _Float32 __z)
+ { return std::__hypot3<_Float32>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ inline _Float64
+ hypot(_Float64 __x, _Float64 __y, _Float64 __z)
+ { return std::__hypot3<_Float64>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) \
+ && (defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) \
+ || defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+ inline _Float128
+ hypot(_Float128 __x, _Float128 __y, _Float128 __z)
+ { return std::__hypot3<_Float128>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ inline __gnu_cxx::__bfloat16_t
+ hypot(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __z)
+ { return std::__hypot3<__gnu_cxx::__bfloat16_t>(__x, __y, __z); }
+#endif
+
#endif // C++17
#if __cplusplus >= 202002L
@@ -1928,6 +3580,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __type = __gnu_cxx::__promoted_t<_Tp, _Up, _Vp>;
return std::__lerp<__type>(__x, __y, __z);
}
+
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ inline _Float16
+ lerp(_Float16 __x, _Float16 __y, _Float16 __z) noexcept
+ { return std::__lerp<_Float16>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ inline _Float32
+ lerp(_Float32 __x, _Float32 __y, _Float32 __z) noexcept
+ { return std::__lerp<_Float32>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ inline _Float64
+ lerp(_Float64 __x, _Float64 __y, _Float64 __z) noexcept
+ { return std::__lerp<_Float64>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) \
+ && (defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128) \
+ || defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+ inline _Float128
+ lerp(_Float128 __x, _Float128 __y, _Float128 __z) noexcept
+ { return std::__lerp<_Float128>(__x, __y, __z); }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ inline __gnu_cxx::__bfloat16_t
+ lerp(__gnu_cxx::__bfloat16_t __x, __gnu_cxx::__bfloat16_t __y, __gnu_cxx::__bfloat16_t __z) noexcept
+ { return std::__lerp<__gnu_cxx::__bfloat16_t>(__x, __y, __z); }
+#endif
+
#endif // C++20
_GLIBCXX_END_NAMESPACE_VERSION
@@ -190,6 +190,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __promote<float>
{ typedef float __type; };
+#ifdef __STDCPP_FLOAT16_T__
+ template<>
+ struct __promote<_Float16>
+ { typedef _Float16 __type; };
+#endif
+
+#ifdef __STDCPP_FLOAT32_T__
+ template<>
+ struct __promote<_Float32>
+ { typedef _Float32 __type; };
+#endif
+
+#ifdef __STDCPP_FLOAT64_T__
+ template<>
+ struct __promote<_Float64>
+ { typedef _Float64 __type; };
+#endif
+
+#ifdef __STDCPP_FLOAT128_T__
+ template<>
+ struct __promote<_Float128>
+ { typedef _Float128 __type; };
+#endif
+
+#ifdef __STDCPP_BFLOAT16_T__
+ template<>
+ struct __promote<__gnu_cxx::__bfloat16_t>
+ { typedef __gnu_cxx::__bfloat16_t __type; };
+#endif
+
#if __cpp_fold_expressions
template<typename... _Tp>
@@ -95,6 +95,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 \
@@ -452,6 +452,7 @@ std_freestanding = \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/stack \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/stacktrace \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/stdexcept \
+@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/stdfloat \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/stop_token \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/streambuf \
@GLIBCXX_HOSTED_TRUE@ ${std_srcdir}/string \
@@ -228,6 +228,7 @@
# include <stacktrace>
#endif
#include <stdatomic.h>
+#include <stdfloat>
#endif
#endif // HOSTED
@@ -49,6 +49,17 @@
// version dynamically in case it has changed since libstdc++ was configured.
#define _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC __GLIBC_PREREQ(2,23)
+// Glibc 2.26 on i?86/x86-64/ia64/ppc64le added *f128 support.
+// Glibc 2.27 added it also on many other arches but those have IEEE quad
+// long double.
+#if __GLIBC_PREREQ(2, 26) \
+ && (defined(__i386__) || defined(__x86_64__) || defined (__ia64__) \
+ || (defined(__powerpc__) && defined(_ARCH_PWR8) \
+ && defined(__LITTLE_ENDIAN__) && (_CALL_ELF == 2) \
+ && defined(__FLOAT128__)))
+# define _GLIBCXX_HAVE_FLOAT128_MATH 1
+#endif
+
#if __GLIBC_PREREQ(2, 27)
// Since glibc 2.27 pthread_self() is usable without linking to libpthread.
# define _GLIBCXX_NATIVE_THREAD_ID pthread_self()
@@ -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
+}
@@ -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
+}
@@ -0,0 +1,96 @@
+// 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-do link { target c++23 } }
+// { dg-excess-errors "" { target uclibc } }
+
+#include <cmath>
+#include <stdfloat>
+
+void fpclassify() { }
+
+void isfinite() { }
+
+void isinf() { }
+
+void isnan() { }
+
+void isnormal() { }
+
+void signbit() { }
+
+void isgreater() { }
+
+void isgreaterequal() { }
+
+void isless() { }
+
+void islessequal() { }
+
+void islessgreater() { }
+
+void isunordered() { }
+
+#if _GLIBCXX_USE_C99_MATH
+template <typename _Tp, typename _Up = _Tp>
+ void test_c99_classify()
+ {
+ typedef _Tp fp_type_one;
+ typedef _Up fp_type_two;
+ fp_type_one f1 = _Tp(1.0);
+ fp_type_two f2 = _Up(3.0);
+ int resi;
+ volatile bool res;
+
+ resi = std::fpclassify(f1);
+ res = std::isfinite(f2);
+ res = std::isinf(f1);
+ res = std::isnan(f2);
+ res = std::isnormal(f1);
+ res = std::signbit(f2);
+ res = std::isgreater(f1, f2);
+ res = std::isgreaterequal(f1, f2);
+ res = std::isless(f1, f2);
+ res = std::islessequal(f1,f2);
+ res = std::islessgreater(f1, f2);
+ res = std::isunordered(f1, f2);
+ resi = resi; // Suppress unused warning.
+ res = res;
+ }
+#endif
+
+int main()
+{
+#if _GLIBCXX_USE_C99_MATH
+#ifdef __STDCPP_FLOAT16_T__
+ test_c99_classify<std::float16_t>();
+#endif
+#ifdef __STDCPP_FLOAT32_T__
+ test_c99_classify<std::float32_t>();
+#endif
+#ifdef __STDCPP_FLOAT64_T__
+ test_c99_classify<std::float64_t>();
+#endif
+#ifdef __STDCPP_FLOAT128_T__
+ test_c99_classify<std::float128_t>();
+#endif
+#ifdef __STDCPP_BFLOAT16_T__
+ test_c99_classify<std::bfloat16_t>();
+#endif
+#endif
+ return 0;
+}
@@ -0,0 +1,146 @@
+// 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-do link { target c++23 } }
+
+#include <stdfloat>
+#include <cmath>
+
+template <typename T>
+__attribute__((__noipa__)) void
+test_functions (T *p, int *q, long int *r, long long int *s)
+{
+ p[0] = std::acos (p[0]);
+ p[1] = std::asin (p[1]);
+ p[2] = std::atan (p[2]);
+ p[3] = std::cos (p[3]);
+ p[4] = std::sin (p[4]);
+ p[5] = std::tan (p[5]);
+ p[6] = std::acosh (p[6]);
+ p[7] = std::asinh (p[7]);
+ p[8] = std::atanh (p[8]);
+ p[9] = std::cosh (p[9]);
+ p[10] = std::sinh (p[10]);
+ p[11] = std::tanh (p[11]);
+ p[12] = std::exp (p[12]);
+ p[13] = std::exp2 (p[13]);
+ p[14] = std::expm1 (p[14]);
+ p[15] = std::log (p[15]);
+ p[16] = std::log10 (p[16]);
+ p[17] = std::log1p (p[17]);
+ p[18] = std::log2 (p[18]);
+ p[19] = std::logb (p[19]);
+ p[20] = std::cbrt (p[20]);
+ p[21] = std::fabs (p[21]);
+ p[22] = std::sqrt (p[22]);
+ p[23] = std::erf (p[23]);
+ p[24] = std::erfc (p[24]);
+ p[25] = std::lgamma (p[25]);
+ p[26] = std::tgamma (p[26]);
+ p[27] = std::ceil (p[27]);
+ p[28] = std::floor (p[28]);
+ p[29] = std::nearbyint (p[29]);
+ p[30] = std::rint (p[30]);
+ p[31] = std::round (p[31]);
+ p[32] = std::trunc (p[32]);
+ p[33] = std::atan2 (p[33], p[100]);
+ p[34] = std::hypot (p[34], p[101]);
+ p[35] = std::pow (p[35], p[102]);
+ p[36] = std::fmod (p[36], p[103]);
+ p[37] = std::remainder (p[37], p[104]);
+ p[38] = std::copysign (p[38], p[105]);
+// p[39] = std::nextafter (p[39], p[106]);
+ p[40] = std::fdim (p[40], p[107]);
+ p[41] = std::fmax (p[41], p[108]);
+ p[42] = std::fmin (p[42], p[109]);
+ p[43] = std::atan2 (p[43], p[110]);
+ p[44] = std::frexp (p[44], q + 0);
+ q[1] = std::ilogb (p[45]);
+ p[46] = std::ldexp (p[46], q[2]);
+ p[47] = std::modf (p[47], p + 111);
+ p[48] = std::scalbn (p[48], q[3]);
+ p[49] = std::scalbln (p[49], r[0]);
+ p[50] = std::hypot (p[50], p[111], p[112]);
+ r[1] = std::lrint (p[51]);
+ s[0] = std::llrint (p[52]);
+ r[2] = std::lround (p[53]);
+ s[1] = std::llround (p[54]);
+ p[55] = std::remquo (p[55], p[113], q + 4);
+ p[56] = std::fma (p[56], p[114], p[115]);
+ p[57] = std::lerp (p[57], p[116], p[117]);
+ p[58] = std::assoc_laguerre (q[5], q[6], p[58]);
+ p[59] = std::assoc_legendre (q[7], q[8], p[59]);
+ p[60] = std::beta (p[60], p[118]);
+ p[61] = std::comp_ellint_1 (p[61]);
+ p[62] = std::comp_ellint_2 (p[62]);
+ p[63] = std::comp_ellint_3 (p[63], p[119]);
+ p[64] = std::cyl_bessel_i (p[64], p[120]);
+ p[65] = std::cyl_bessel_j (p[65], p[121]);
+ p[66] = std::cyl_bessel_k (p[66], p[122]);
+ p[67] = std::cyl_neumann (p[67], p[123]);
+ p[68] = std::ellint_1 (p[68], p[124]);
+ p[69] = std::ellint_2 (p[69], p[125]);
+ p[70] = std::ellint_3 (p[70], p[126], p[127]);
+ p[71] = std::expint (p[71]);
+ p[72] = std::hermite (q[9], p[72]);
+ p[73] = std::laguerre (q[10], p[73]);
+ p[74] = std::legendre (q[11], p[72]);
+ p[75] = std::riemann_zeta (p[75]);
+ p[76] = std::sph_bessel (q[12], p[76]);
+ p[77] = std::sph_legendre (q[13], q[14], p[77]);
+ p[78] = std::sph_neumann (q[15], q[16], p[78]);
+}
+
+int
+main ()
+{
+ int q[17] = {};
+ long int r[16] = {};
+ long long int s[16] = {};
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ {
+ std::float16_t p[128] = {};
+ test_functions (p, q, r, s);
+ }
+#endif
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ {
+ std::float32_t p[128] = {};
+ test_functions (p, q, r, s);
+ }
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ {
+ std::float64_t p[128] = {};
+ test_functions (p, q, r, s);
+ }
+#endif
+#if defined(__STDCPP_FLOAT128_T__) \
+ && (defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY128) \
+ || defined(_GLIBCXX_HAVE_FLOAT128_MATH))
+ {
+ std::float128_t p[128] = {};
+ test_functions (p, q, r, s);
+ }
+#endif
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ {
+ std::bfloat16_t p[128] = {};
+ test_functions (p, q, r, s);
+ }
+#endif
+}
@@ -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
@@ -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