@@ -675,6 +675,45 @@ namespace __detail
from_chars_result
from_chars(const char* __first, const char* __last, long double& __value,
chars_format __fmt = chars_format::general) noexcept;
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ inline from_chars_result
+ from_chars(const char* __first, const char* __last, _Float32& __value,
+ chars_format __fmt = chars_format::general) noexcept
+ {
+ float __val;
+ from_chars_result __res = from_chars(__first, __last, __val, __fmt);
+ if (__res.ec == errc{})
+ __value = __val;
+ return __res;
+ }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ inline from_chars_result
+ from_chars(const char* __first, const char* __last, _Float64& __value,
+ chars_format __fmt = chars_format::general) noexcept
+ {
+ double __val;
+ from_chars_result __res = from_chars(__first, __last, __val, __fmt);
+ if (__res.ec == errc{})
+ __value = __val;
+ return __res;
+ }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+ inline from_chars_result
+ from_chars(const char* __first, const char* __last, _Float128& __value,
+ chars_format __fmt = chars_format::general) noexcept
+ {
+ long double __val;
+ from_chars_result __res = from_chars(__first, __last, __val, __fmt);
+ if (__res.ec == errc{})
+ __value = __val;
+ return __res;
+ }
+#endif
#endif
#if defined __cpp_lib_to_chars
@@ -701,6 +740,53 @@ namespace __detail
chars_format __fmt) noexcept;
to_chars_result to_chars(char* __first, char* __last, long double __value,
chars_format __fmt, int __precision) noexcept;
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ inline to_chars_result
+ to_chars(char* __first, char* __last, _Float32 __value) noexcept
+ { return to_chars(__first, __last, float(__value)); }
+ inline to_chars_result
+ to_chars(char* __first, char* __last, _Float32 __value,
+ chars_format __fmt) noexcept
+ { return to_chars(__first, __last, float(__value), __fmt); }
+ inline to_chars_result
+ to_chars(char* __first, char* __last, _Float32 __value,
+ chars_format __fmt, int __precision) noexcept
+ { return to_chars(__first, __last, float(__value), __fmt, __precision); }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ inline to_chars_result
+ to_chars(char* __first, char* __last, _Float64 __value) noexcept
+ { return to_chars(__first, __last, double(__value)); }
+ inline to_chars_result
+ to_chars(char* __first, char* __last, _Float64 __value,
+ chars_format __fmt) noexcept
+ { return to_chars(__first, __last, double(__value), __fmt); }
+ inline to_chars_result
+ to_chars(char* __first, char* __last, _Float64 __value,
+ chars_format __fmt, int __precision) noexcept
+ { return to_chars(__first, __last, double(__value), __fmt, __precision); }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+ inline to_chars_result
+ to_chars(char* __first, char* __last, _Float128 __value) noexcept
+ { return to_chars(__first, __last, static_cast<long double>(__value)); }
+ inline to_chars_result
+ to_chars(char* __first, char* __last, _Float128 __value,
+ chars_format __fmt) noexcept
+ {
+ return to_chars(__first, __last, static_cast<long double>(__value), __fmt);
+ }
+ inline to_chars_result
+ to_chars(char* __first, char* __last, _Float128 __value,
+ chars_format __fmt, int __precision) noexcept
+ {
+ return to_chars(__first, __last, static_cast<long double>(__value), __fmt,
+ __precision);
+ }
+#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
@@ -225,6 +225,94 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return _M_extract(__f); }
///@}
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ __attribute__((__always_inline__))
+ __istream_type&
+ operator>>(_Float16& __f)
+ {
+ float __flt;
+ __istream_type& __ret = _M_extract(__flt);
+ ios_base::iostate __err = ios_base::goodbit;
+ if (__flt < -__FLT16_MAX__)
+ {
+ __f = -__FLT16_MAX__;
+ __err = ios_base::failbit;
+ }
+ else if (__flt > __FLT16_MAX__)
+ {
+ __f = __FLT16_MAX__;
+ __err = ios_base::failbit;
+ }
+ else
+ __f = static_cast<_Float16>(__flt);
+ if (__err)
+ this->setstate(__err);
+ return __ret;
+ }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ __attribute__((__always_inline__))
+ __istream_type&
+ operator>>(_Float32& __f)
+ {
+ float __flt;
+ __istream_type& __ret = _M_extract(__flt);
+ __f = static_cast<_Float32> (__flt);
+ return __ret;
+ }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ __attribute__((__always_inline__))
+ __istream_type&
+ operator>>(_Float64& __f)
+ {
+ double __dbl;
+ __istream_type& __ret = _M_extract(__dbl);
+ __f = static_cast<_Float64> (__dbl);
+ return __ret;
+ }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+ __attribute__((__always_inline__))
+ __istream_type&
+ operator>>(_Float128& __f)
+ {
+ long double __ldbl;
+ __istream_type& __ret = _M_extract(__ldbl);
+ __f = static_cast<_Float128> (__ldbl);
+ return __ret;
+ }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ __attribute__((__always_inline__))
+ __istream_type&
+ operator>>(__gnu_cxx::__bfloat16_t & __f)
+ {
+ float __flt;
+ __istream_type& __ret = _M_extract(__flt);
+ ios_base::iostate __err = ios_base::goodbit;
+ if (__flt < -__BFLT16_MAX__)
+ {
+ __f = -__BFLT16_MAX__;
+ __err = ios_base::failbit;
+ }
+ else if (__flt > __BFLT16_MAX__)
+ {
+ __f = __BFLT16_MAX__;
+ __err = ios_base::failbit;
+ }
+ else
+ __f = static_cast<__gnu_cxx::__bfloat16_t>(__flt);
+ if (__err)
+ this->setstate(__err);
+ return __ret;
+ }
+#endif
+
/**
* @brief Basic arithmetic extractors
* @param __p A variable of pointer type.
@@ -235,6 +235,51 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return _M_insert(__f); }
///@}
+#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ __attribute__((__always_inline__))
+ __ostream_type&
+ operator<<(_Float16 __f)
+ {
+ return _M_insert(static_cast<double>(__f));
+ }
+#endif
+
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ __attribute__((__always_inline__))
+ __ostream_type&
+ operator<<(_Float32 __f)
+ {
+ return _M_insert(static_cast<double>(__f));
+ }
+#endif
+
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ __attribute__((__always_inline__))
+ __ostream_type&
+ operator<<(_Float64 __f)
+ {
+ return _M_insert(static_cast<double>(__f));
+ }
+#endif
+
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+ __attribute__((__always_inline__))
+ __ostream_type&
+ operator<<(_Float128 __f)
+ {
+ return _M_insert(static_cast<long double>(__f));
+ }
+#endif
+
+#if defined(__STDCPP_BFLOAT16_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ __attribute__((__always_inline__))
+ __ostream_type&
+ operator<<(__gnu_cxx::__bfloat16_t __f)
+ {
+ return _M_insert(static_cast<double>(__f));
+ }
+#endif
+
/**
* @brief Pointer arithmetic inserters
* @param __p A variable of pointer type.
@@ -0,0 +1,367 @@
+// Copyright (C) 2020-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 run { target c++23 } }
+// { dg-add-options ieee }
+
+#include <charconv>
+#include <string>
+#include <limits>
+#include <stdfloat>
+#include <cmath>
+#include <cstdlib>
+#include <testsuite_hooks.h>
+
+// Test std::from_chars floating-point conversions.
+
+#if __cpp_lib_to_chars >= 201611L
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+void
+test01()
+{
+ std::string s;
+ std::float64_t f64;
+ std::from_chars_result res;
+
+ for (auto fmt : { std::chars_format::fixed, std::chars_format::scientific,
+ std::chars_format::general, std::chars_format::hex })
+ {
+ s = "Info";
+ res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
+ VERIFY( std::isinf(f64) );
+ VERIFY( res.ptr == s.data() + 3 );
+ VERIFY( res.ec == std::errc{} );
+
+ s = "-INFIN";
+ res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
+ VERIFY( std::isinf(f64) );
+ VERIFY( f64 < 0 );
+ VERIFY( res.ptr == s.data() + 4 );
+ VERIFY( res.ec == std::errc{} );
+
+ s = "InFiNiTy aNd BeYoNd";
+ res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
+ VERIFY( std::isinf(f64) );
+ VERIFY( res.ptr == s.data() + 8 );
+ VERIFY( res.ec == std::errc{} );
+
+ s = "nAn";
+ res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
+ VERIFY( std::isnan(f64) );
+ VERIFY( res.ptr == s.data() + 3 );
+ VERIFY( res.ec == std::errc{} );
+
+ s = "-NAN()";
+ res = std::from_chars(s.data(), s.data() + s.length(), f64, fmt);
+ VERIFY( std::isnan(f64) );
+ VERIFY( res.ptr == s.data() + s.length() );
+ VERIFY( res.ec == std::errc{} );
+ }
+}
+
+void
+test02()
+{
+ std::string s;
+ std::float64_t f64 = 1.0f64;
+ std::from_chars_result res;
+
+ s = "0x123";
+ res = std::from_chars(s.data(), s.data() + s.length(), f64);
+ VERIFY( f64 == 0.0f64 );
+ VERIFY( res.ptr == s.data() + 1 );
+ VERIFY( res.ec == std::errc{} );
+
+ f64 = 1.0f64;
+ res = std::from_chars(s.data(), s.data() + s.length(), f64,
+ std::chars_format::fixed);
+ VERIFY( f64 == 0.0f64 );
+ VERIFY( res.ptr == s.data() + 1 );
+ VERIFY( res.ec == std::errc{} );
+
+ f64 = 1.0f64;
+ res = std::from_chars(s.data(), s.data() + s.length(), f64,
+ std::chars_format::scientific);
+ VERIFY( f64 == 1.0f64 );
+ VERIFY( res.ptr == s.data() );
+ VERIFY( res.ec == std::errc::invalid_argument );
+
+ f64 = 1.0f64;
+ res = std::from_chars(s.data(), s.data() + s.length(), f64,
+ std::chars_format::general);
+ VERIFY( f64 == 0.0f64 );
+ VERIFY( res.ptr == s.data() + 1 );
+ VERIFY( res.ec == std::errc{} );
+
+ f64 = 1.0f64;
+ res = std::from_chars(s.data(), s.data() + s.length(), f64,
+ std::chars_format::hex);
+ VERIFY( f64 == 0.0f64 );
+ VERIFY( res.ptr == s.data() + 1 );
+ VERIFY( res.ec == std::errc{} );
+}
+
+void
+test03()
+{
+ std::string s;
+ std::float64_t f64 = 1.0f64;
+ std::from_chars_result res;
+
+ s = "0.5e+2azzz";
+ res = std::from_chars(s.data(), s.data() + s.length(), f64);
+ VERIFY( f64 == 0.5e+2f64 );
+ VERIFY( res.ptr == s.data() + s.length() - 1 - 3 );
+ VERIFY( res.ec == std::errc{} );
+
+ res = std::from_chars(s.data(), s.data() + s.length(), f64,
+ std::chars_format::fixed);
+ VERIFY( f64 == 0.5f64 );
+ VERIFY( res.ptr == s.data() + 3 );
+ VERIFY( res.ec == std::errc{} );
+
+ f64 = 1.0f64;
+ res = std::from_chars(s.data(), s.data() + s.length(), f64,
+ std::chars_format::scientific);
+ VERIFY( f64 == 0.5e+2f64 );
+ VERIFY( res.ptr == s.data() + s.length() - 1 - 3 );
+ VERIFY( res.ec == std::errc{} );
+
+ f64 = 1.0f64;
+ res = std::from_chars(s.data(), s.data() + s.length(), f64,
+ std::chars_format::general);
+ VERIFY( f64 == 0.5e+2f64 );
+ VERIFY( res.ptr == s.data() + s.length() - 1 - 3 );
+ VERIFY( res.ec == std::errc{} );
+
+ f64 = 1.0;
+ res = std::from_chars(s.data(), s.data() + s.length(), f64,
+ std::chars_format::hex);
+ VERIFY( f64 == 0x0.5Ep0f64 );
+ VERIFY( res.ptr == s.data() + 4 );
+ VERIFY( res.ec == std::errc{} );
+
+ s = "1.Ap-2zzz";
+ res = std::from_chars(s.data(), s.data() + s.length(), f64,
+ std::chars_format::hex);
+ VERIFY( f64 == 0.40625f64 );
+ VERIFY( res.ptr == s.data() + s.length() - 3 );
+ VERIFY( res.ec == std::errc{} );
+}
+
+void
+test04()
+{
+ // Huge input strings
+ std::string s(1000, '0');
+ std::float64_t f64 = 1.0f64;
+ std::from_chars_result res;
+ res = std::from_chars(s.data(), s.data() + s.length(), f64);
+ VERIFY( res.ptr == s.data() + s.length() );
+ VERIFY( res.ec == std::errc{} );
+ VERIFY( f64 == 0.0f64 );
+
+ s += ".5";
+ res = std::from_chars(s.data(), s.data() + s.length(), f64);
+ VERIFY( res.ptr == s.data() + s.length() );
+ VERIFY( res.ec == std::errc{} );
+ VERIFY( f64 == 0.5f64 );
+
+ s += "e2";
+ auto len = s.length();
+ s += std::string(1000, 'a');
+ res = std::from_chars(s.data(), s.data() + s.length(), f64);
+ VERIFY( res.ptr == s.data() + len );
+ VERIFY( res.ec == std::errc{} );
+ VERIFY( f64 == 50.f64 );
+}
+#endif
+
+using std::to_string;
+
+#ifdef __GLIBCXX_TYPE_INT_N_0
+std::string
+to_string(unsigned __GLIBCXX_TYPE_INT_N_0 val)
+{
+ using Limits = std::numeric_limits<unsigned __GLIBCXX_TYPE_INT_N_0>;
+ std::string s(Limits::digits10+2, '0');
+ for (auto iter = s.end(); val != 0; val /= 10)
+ *--iter = '0' + (val % 10);
+ return s;
+}
+#endif
+
+template<typename FloatT>
+void
+test_small_num()
+{
+ std::from_chars_result res;
+ FloatT flt;
+
+ // Small integer values that are exactly representable
+
+ for (int i = 0; i < 100; ++i)
+ {
+ std::string s = to_string(i);
+ int len = s.length();
+ s += "123";
+ const char* s1 = s.c_str();
+ const char* s1_end = s1 + len;
+
+ for (auto fmt : { std::chars_format::fixed,
+ std::chars_format::general,
+ std::chars_format::hex })
+ {
+ if (fmt == std::chars_format::hex && i > 9)
+ continue;
+
+ res = std::from_chars(s1, s1_end, flt, fmt);
+ VERIFY( res.ec == std::errc{} );
+ VERIFY( res.ptr == s1_end );
+ VERIFY( flt == i );
+ }
+
+ if (i > 9)
+ continue;
+
+ // Test single-digit integers with small exponents.
+
+ const char s2[] = { '.', *s1, 'e', '0', '0', '0', '1' };
+ const char* s2_end = s2 + sizeof(s2);
+
+ const char s3[] = { *s1, '0', 'e', '-', '0', '0', '1' };
+ const char* s3_end = s3 + sizeof(s3);
+
+ for (auto fmt : { std::chars_format::scientific,
+ std::chars_format::general })
+ {
+ res = std::from_chars(s2, s2_end, flt, fmt);
+ VERIFY( res.ec == std::errc{} );
+ VERIFY( res.ptr == s2_end );
+ VERIFY( flt == i );
+
+ res = std::from_chars(s3, s3_end, flt, fmt);
+ VERIFY( res.ec == std::errc{} );
+ VERIFY( res.ptr == s3_end );
+ VERIFY( flt == i );
+ }
+ }
+}
+
+void
+test05()
+{
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ test_small_num<std::float32_t>();
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ test_small_num<std::float64_t>();
+#endif
+#if defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+ test_small_num<std::float128_t>();
+#endif
+}
+
+template<typename FloatT, typename UIntT>
+void
+test_max_mantissa()
+{
+ using Float_limits = std::numeric_limits<FloatT>;
+ using UInt_limits = std::numeric_limits<UIntT>;
+
+ if (Float_limits::is_iec559 && Float_limits::digits < UInt_limits::digits)
+ {
+#ifdef _GLIBCXX_USE_C99_MATH_TR1
+ std::printf("Testing %d-bit float, using %zu-bit integer\n",
+ Float_limits::digits + (int)std::log2(Float_limits::max_exponent) + 1,
+ sizeof(UIntT) * __CHAR_BIT__);
+#endif
+
+ std::from_chars_result res;
+ FloatT flt;
+
+ for (int i = 0; i < 10; ++i)
+ {
+ // (1 << digits) - 1 is the maximum value of the mantissa
+ const auto val = ((UIntT)1 << Float_limits::digits) - 1 - i;
+ std::string s = to_string(val);
+ auto len = s.length();
+ s += "000"; // these should be ignored
+ for (auto fmt : { std::chars_format::fixed,
+ std::chars_format::general })
+ {
+ res = std::from_chars(s.data(), s.data() + len, flt, fmt);
+ VERIFY( res.ec == std::errc{} );
+ VERIFY( res.ptr == s.data() + len );
+ VERIFY( flt == val );
+ }
+ s.resize(len);
+ const auto orig_len = len;
+ s += "e+000";
+ len = s.length();
+ s += "111";
+ for (auto fmt : { std::chars_format::scientific,
+ std::chars_format::general })
+ {
+ res = std::from_chars(s.data(), s.data() + len, flt, fmt);
+ VERIFY( res.ec == std::errc{} );
+ VERIFY( res.ptr == s.data() + len );
+ VERIFY( flt == val );
+
+ std::string s2 = s.substr(0, len - 5);
+ s2.insert(s2.begin() + orig_len - 1, '.');
+ s2 += "e000000000001";
+ res = std::from_chars(s.data(), s.data() + len, flt, fmt);
+ VERIFY( res.ec == std::errc{} );
+ VERIFY( res.ptr == s.data() + len );
+ VERIFY( flt == val );
+ }
+ }
+ }
+}
+
+void
+test06()
+{
+#if defined(__STDCPP_FLOAT32_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
+ test_max_mantissa<std::float32_t, unsigned long>();
+#endif
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ test_max_mantissa<std::float64_t, unsigned long long>();
+#endif
+#if defined(__GLIBCXX_TYPE_INT_N_0) \
+ && defined(__STDCPP_FLOAT128_T__) && defined(_GLIBCXX_LDOUBLE_IS_IEEE_BINARY128)
+ test_max_mantissa<std::float128_t, unsigned __GLIBCXX_TYPE_INT_N_0>();
+#endif
+}
+#endif
+
+int
+main()
+{
+#if __cpp_lib_to_chars >= 201611L
+#if defined(__STDCPP_FLOAT64_T__) && defined(_GLIBCXX_DOUBLE_IS_IEEE_BINARY64)
+ test01();
+ test02();
+ test03();
+ test04();
+#endif
+ test05();
+ test06();
+#endif
+}
@@ -29,77 +29,77 @@ test ()
{
using lim = std::numeric_limits<T>;
T t0 = std::nextafter(T(-0.0), T(2.0));
- VERIFY(t0 == lim::denorm_min());
+ VERIFY( t0 == lim::denorm_min() );
T t1 = std::nextafter(T(), T(1.0));
- VERIFY(t1 == lim::denorm_min());
+ VERIFY( t1 == lim::denorm_min() );
T t2 = std::nextafter(T(), T());
- VERIFY(t2 == T() && !std::signbit(t2));
+ VERIFY( t2 == T() && !std::signbit(t2) );
T t3 = std::nextafter(lim::denorm_min(), T(-2.0));
- VERIFY(t3 == T() && !std::signbit(t3));
+ VERIFY( t3 == T() && !std::signbit(t3) );
T t4 = std::nextafter(lim::min(), T(-0.0));
- VERIFY(std::fpclassify(t4) == FP_SUBNORMAL && t4 > T());
+ VERIFY( std::fpclassify(t4) == FP_SUBNORMAL && t4 > T() );
T t5 = std::nextafter(t4, T(1.0));
- VERIFY(t5 == lim::min());
+ VERIFY( t5 == lim::min() );
T t6 = std::nextafter(lim::min(), lim::infinity());
- VERIFY(std::fpclassify(t6) == FP_NORMAL && t6 > lim::min());
+ VERIFY( std::fpclassify(t6) == FP_NORMAL && t6 > lim::min() );
T t7 = std::nextafter(t6, -lim::infinity());
- VERIFY(t7 == lim::min());
+ VERIFY( t7 == lim::min() );
T t8 = std::nextafter(T(16.0), T(16.5));
- VERIFY(t8 > t7);
+ VERIFY( t8 > t7 );
T t9 = std::nextafter(t8, T(15.5));
- VERIFY(t9 == T(16.0));
+ VERIFY( t9 == T(16.0) );
T t10 = std::nextafter(lim::max(), T(-0.5));
- VERIFY(std::fpclassify(t10) == FP_NORMAL && t10 < lim::max());
+ VERIFY( std::fpclassify(t10) == FP_NORMAL && t10 < lim::max() );
T t11 = std::nextafter(t10, lim::infinity());
- VERIFY(t11 == lim::max());
+ VERIFY( t11 == lim::max() );
T t12 = std::nextafter(t11, lim::infinity());
- VERIFY(std::fpclassify(t12) == FP_INFINITE && !std::signbit(t12));
+ VERIFY( std::fpclassify(t12) == FP_INFINITE && !std::signbit(t12) );
T t13 = std::nextafter(lim::infinity(), t12);
- VERIFY(t13 == t12);
+ VERIFY( t13 == t12 );
T t14 = std::nextafter(t13, T(1.0));
- VERIFY(t14 == lim::max());
+ VERIFY( t14 == lim::max() );
T t15 = std::nextafter(lim::quiet_NaN(), T());
- VERIFY(std::fpclassify(t15) == FP_NAN);
+ VERIFY( std::fpclassify(t15) == FP_NAN );
T t16 = std::nextafter(T(17.0), lim::quiet_NaN());
- VERIFY(std::fpclassify(t16) == FP_NAN);
+ VERIFY( std::fpclassify(t16) == FP_NAN );
T t17 = std::nextafter(T(), T(-0.0));
- VERIFY(t17 == T() && std::signbit(t17));
+ VERIFY( t17 == T() && std::signbit(t17) );
T t20 = std::nextafter(T(-0.0), T(-2.0));
- VERIFY(t20 == -lim::denorm_min());
+ VERIFY( t20 == -lim::denorm_min() );
T t21 = std::nextafter(T(), T(-1.0));
- VERIFY(t21 == -lim::denorm_min());
+ VERIFY( t21 == -lim::denorm_min() );
T t22 = std::nextafter(T(-0.0), T(-0.0));
- VERIFY(t22 == T() && std::signbit(t22));
+ VERIFY( t22 == T() && std::signbit(t22) );
T t23 = std::nextafter(-lim::denorm_min(), T(2.0));
- VERIFY(t23 == T() && std::signbit(t23));
+ VERIFY( t23 == T() && std::signbit(t23) );
T t24 = std::nextafter(-lim::min(), T());
- VERIFY(std::fpclassify(t24) == FP_SUBNORMAL && t24 < T());
+ VERIFY( std::fpclassify(t24) == FP_SUBNORMAL && t24 < T() );
T t25 = std::nextafter(t24, T(-1.0));
- VERIFY(t25 == -lim::min());
+ VERIFY( t25 == -lim::min() );
T t26 = std::nextafter(-lim::min(), -lim::infinity());
- VERIFY(std::fpclassify(t26) == FP_NORMAL && t26 < -lim::min());
+ VERIFY( std::fpclassify(t26) == FP_NORMAL && t26 < -lim::min() );
T t27 = std::nextafter(t26, lim::infinity());
- VERIFY(t27 == -lim::min());
+ VERIFY( t27 == -lim::min() );
T t28 = std::nextafter(T(-16.0), T(-16.5));
- VERIFY(t28 < t27);
+ VERIFY( t28 < t27 );
T t29 = std::nextafter(t28, T(-15.5));
- VERIFY(t29 == T(-16.0));
+ VERIFY( t29 == T(-16.0) );
T t30 = std::nextafter(-lim::max(), T(0.5));
- VERIFY(std::fpclassify(t30) == FP_NORMAL && t30 > -lim::max());
+ VERIFY( std::fpclassify(t30) == FP_NORMAL && t30 > -lim::max() );
T t31 = std::nextafter(t30, -lim::infinity());
- VERIFY(t31 == -lim::max());
+ VERIFY( t31 == -lim::max() );
T t32 = std::nextafter(t31, -lim::infinity());
- VERIFY(std::fpclassify(t32) == FP_INFINITE && std::signbit(t32));
+ VERIFY( std::fpclassify(t32) == FP_INFINITE && std::signbit(t32) );
T t33 = std::nextafter(-lim::infinity(), t32);
- VERIFY(t33 == t32);
+ VERIFY( t33 == t32 );
T t34 = std::nextafter(t33, T(-1.0));
- VERIFY(t34 == -lim::max());
+ VERIFY( t34 == -lim::max() );
T t35 = std::nextafter(-lim::quiet_NaN(), T());
- VERIFY(std::fpclassify(t35) == FP_NAN);
+ VERIFY( std::fpclassify(t35) == FP_NAN );
T t36 = std::nextafter(T(-17.0), lim::quiet_NaN());
- VERIFY(std::fpclassify(t36) == FP_NAN);
+ VERIFY( std::fpclassify(t36) == FP_NAN );
T t37 = std::nextafter(T(-0.0), T());
- VERIFY(t37 == T() && !std::signbit(t37));
+ VERIFY( t37 == T() && !std::signbit(t37) );
}
int
@@ -15,6 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+// { dg-options "-std=gnu++2b" }
// { dg-do link { target c++23 } }
#include <stdfloat>
@@ -22,91 +23,91 @@
template <typename T>
__attribute__((__noipa__)) void
-test_functions (T *p, int *q, long int *r, long long int *s)
+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], p[78]);
+ 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], p[78]);
}
int
-main ()
+main()
{
int q[16] = {};
long int r[16] = {};
@@ -114,19 +115,19 @@ main ()
#if defined(__STDCPP_FLOAT16_T__) && defined(_GLIBCXX_FLOAT_IS_IEEE_BINARY32)
{
std::float16_t p[128] = {};
- test_functions (p, q, r, s);
+ 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);
+ 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);
+ test_functions(p, q, r, s);
}
#endif
#if defined(__STDCPP_FLOAT128_T__) \
@@ -134,13 +135,13 @@ main ()
|| defined(_GLIBCXX_HAVE_FLOAT128_MATH))
{
std::float128_t p[128] = {};
- test_functions (p, q, r, s);
+ 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);
+ test_functions(p, q, r, s);
}
#endif
}
@@ -15,6 +15,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
+// { dg-options "-std=gnu++2b" }
// { dg-do link { target c++23 } }
// { dg-excess-errors "" { target uclibc } }