diff options
Diffstat (limited to 'libstdc++-v3/src/c++17')
-rw-r--r-- | libstdc++-v3/src/c++17/Makefile.am | 7 | ||||
-rw-r--r-- | libstdc++-v3/src/c++17/Makefile.in | 11 | ||||
-rw-r--r-- | libstdc++-v3/src/c++17/floating_from_chars.cc | 38 |
3 files changed, 54 insertions, 2 deletions
diff --git a/libstdc++-v3/src/c++17/Makefile.am b/libstdc++-v3/src/c++17/Makefile.am index 642efb9..37cdb53 100644 --- a/libstdc++-v3/src/c++17/Makefile.am +++ b/libstdc++-v3/src/c++17/Makefile.am @@ -61,6 +61,13 @@ vpath % $(top_srcdir)/src/c++17 libc__17convenience_la_SOURCES = $(sources) $(inst_sources) +if GLIBCXX_LDBL_ALT128_COMPAT +floating_from_chars.lo: floating_from_chars.cc + $(LTCXXCOMPILE) -mabi=ibmlongdouble $(LONG_DOUBLE_128_FLAGS) -c $< +floating_from_chars.o: floating_from_chars.cc + $(CXXCOMPILE) -mabi=ibmlongdouble $(LONG_DOUBLE_128_FLAGS) -c $< +endif + # AM_CXXFLAGS needs to be in each subdirectory so that it can be # modified in a per-library or per-sub-library way. Need to manually # set this option because CONFIG_CXXFLAGS has to be after diff --git a/libstdc++-v3/src/c++17/Makefile.in b/libstdc++-v3/src/c++17/Makefile.in index ce08eb3..ccae721 100644 --- a/libstdc++-v3/src/c++17/Makefile.in +++ b/libstdc++-v3/src/c++17/Makefile.in @@ -262,6 +262,8 @@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ +LONG_DOUBLE_128_FLAGS = @LONG_DOUBLE_128_FLAGS@ +LONG_DOUBLE_ALT128_COMPAT_FLAGS = @LONG_DOUBLE_ALT128_COMPAT_FLAGS@ LONG_DOUBLE_COMPAT_FLAGS = @LONG_DOUBLE_COMPAT_FLAGS@ LTLIBICONV = @LTLIBICONV@ LTLIBOBJS = @LTLIBOBJS@ @@ -401,11 +403,13 @@ toolexeclibdir = $(glibcxx_toolexeclibdir) @ENABLE_WERROR_TRUE@WERROR_FLAG = -Werror @ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS = @ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates +@GLIBCXX_LDBL_ALT128_COMPAT_FALSE@LDBL_128_FLAGS = +@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@LDBL_128_FLAGS = $(LONG_DOUBLE_128_FLAGS) # These bits are all figured out from configure. Look in acinclude.m4 # or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS. CONFIG_CXXFLAGS = \ - $(SECTION_FLAGS) $(HWCAP_CFLAGS) -frandom-seed=$@ + $(SECTION_FLAGS) $(HWCAP_CFLAGS) -frandom-seed=$@ $(LDBL_128_FLAGS) WARN_CXXFLAGS = \ $(WARN_FLAGS) $(WERROR_FLAG) -fdiagnostics-show-location=once @@ -752,6 +756,11 @@ uninstall-am: vpath % $(top_srcdir)/src/c++17 +@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@floating_from_chars.lo: floating_from_chars.cc +@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ $(LTCXXCOMPILE) -mabi=ibmlongdouble $(LONG_DOUBLE_128_FLAGS) -c $< +@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@floating_from_chars.o: floating_from_chars.cc +@GLIBCXX_LDBL_ALT128_COMPAT_TRUE@ $(CXXCOMPILE) -mabi=ibmlongdouble $(LONG_DOUBLE_128_FLAGS) -c $< + # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/libstdc++-v3/src/c++17/floating_from_chars.cc b/libstdc++-v3/src/c++17/floating_from_chars.cc index c279809..a194335 100644 --- a/libstdc++-v3/src/c++17/floating_from_chars.cc +++ b/libstdc++-v3/src/c++17/floating_from_chars.cc @@ -44,6 +44,14 @@ # include <xlocale.h> #endif +#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT +#ifndef __LONG_DOUBLE_IBM128__ +#error "floating_from_chars.cc must be compiled with -mabi=ibmlongdouble" +#endif +// strtold for __ieee128 +extern "C" __ieee128 __strtoieee128(const char*, char**); +#endif + #if _GLIBCXX_HAVE_USELOCALE namespace std _GLIBCXX_VISIBILITY(default) { @@ -316,6 +324,10 @@ namespace tmpval = std::strtod(str, &endptr); else if constexpr (is_same_v<T, long double>) tmpval = std::strtold(str, &endptr); +# ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT + else if constexpr (is_same_v<T, __ieee128>) + tmpval = __strtoieee128(str, &endptr); +# endif #else tmpval = std::strtod(str, &endptr); #endif @@ -332,7 +344,7 @@ namespace const ptrdiff_t n = endptr - str; if (conv_errno == ERANGE) [[unlikely]] { - if (isinf(tmpval)) // overflow + if (__builtin_isinf(tmpval)) // overflow ec = errc::result_out_of_range; else // underflow (LWG 3081 wants to set value = tmpval here) ec = errc::result_out_of_range; @@ -469,6 +481,8 @@ from_chars(const char* first, const char* last, long double& value, } #ifdef _GLIBCXX_LONG_DOUBLE_COMPAT +// Make std::from_chars for 64-bit long double an alias for the overload +// for double. extern "C" from_chars_result _ZSt10from_charsPKcS0_ReSt12chars_format(const char* first, const char* last, long double& value, @@ -476,6 +490,28 @@ _ZSt10from_charsPKcS0_ReSt12chars_format(const char* first, const char* last, __attribute__((alias ("_ZSt10from_charsPKcS0_RdSt12chars_format"))); #endif +#ifdef _GLIBCXX_LONG_DOUBLE_ALT128_COMPAT +from_chars_result +from_chars(const char* first, const char* last, __ieee128& value, + chars_format fmt) noexcept +{ + buffer_resource mr; + pmr::string buf(&mr); + size_t len = 0; + errc ec = errc::invalid_argument; + __try + { + if (const char* pat = pattern(first, last, fmt, buf)) [[likely]] + len = from_chars_impl(pat, value, ec); + } + __catch (const std::bad_alloc&) + { + fmt = chars_format{}; + } + return make_result(first, len, fmt, ec); +} +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace std #endif // _GLIBCXX_HAVE_USELOCALE |