Message ID | 20240801213927.388966-4-jwakely@redhat.com |
---|---|
State | New |
Headers | show |
Series | libstdc++: Check ios::uppercase for ios::fixed floating-point output [PR114862] | expand |
This is still pending a decision by LEWG, but I've pushed it to trunk anyway. We can always revert it before GCC 15 is released if the committee decides against it, but this way we might get user feedback on it. On Thu, 1 Aug 2024 at 22:41, Jonathan Wakely <jwakely@redhat.com> wrote: > > Tested x86_64-linux. > > -- >8 -- > > This is LWG 4084 which I filed recently. LWG seems to support making the > change, so that std::num_put can use the %F format for floating-point > numbers. > > libstdc++-v3/ChangeLog: > > PR libstdc++/114862 > * src/c++98/locale_facets.cc (__num_base::_S_format_float): > Check uppercase flag for fixed format. > * testsuite/22_locale/num_put/put/char/lwg4084.cc: New test. > --- > libstdc++-v3/src/c++98/locale_facets.cc | 13 ++++-- > .../22_locale/num_put/put/char/lwg4084.cc | 46 +++++++++++++++++++ > 2 files changed, 54 insertions(+), 5 deletions(-) > create mode 100644 libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc > > diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc > index fa469b1b872..02f53fd5ec1 100644 > --- a/libstdc++-v3/src/c++98/locale_facets.cc > +++ b/libstdc++-v3/src/c++98/locale_facets.cc > @@ -84,17 +84,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > > if (__mod) > *__fptr++ = __mod; > - // [22.2.2.2.2] Table 58 > + // C++11 [facet.num.put.virtuals] Table 88 > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 4084. std::fixed ignores std::uppercase > + bool __upper = __flags & ios_base::uppercase; > if (__fltfield == ios_base::fixed) > - *__fptr++ = 'f'; > + *__fptr++ = __upper ? 'F' : 'f'; > else if (__fltfield == ios_base::scientific) > - *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e'; > + *__fptr++ = __upper ? 'E' : 'e'; > #if _GLIBCXX_USE_C99_STDIO > else if (__fltfield == (ios_base::fixed | ios_base::scientific)) > - *__fptr++ = (__flags & ios_base::uppercase) ? 'A' : 'a'; > + *__fptr++ = __upper ? 'A' : 'a'; > #endif > else > - *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g'; > + *__fptr++ = __upper ? 'G' : 'g'; > *__fptr = '\0'; > } > > diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc > new file mode 100644 > index 00000000000..b7c7da11f86 > --- /dev/null > +++ b/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc > @@ -0,0 +1,46 @@ > +// { dg-do run } > +// LWG 4084. std::fixed ignores std::uppercase > +// PR libstdc++/114862 std::uppercase not applying to nan's and inf's > + > +#include <sstream> > +#include <limits> > +#include <iomanip> > +#include <testsuite_hooks.h> > + > +void > +test_nan() > +{ > + std::ostringstream out; > + double nan = std::numeric_limits<double>::quiet_NaN(); > + out << std::fixed; > + out << ' ' << nan << ' ' << -nan; > + out << std::uppercase; > + out << ' ' << nan << ' ' << -nan; > + out << std::showpoint; > + out << ' ' << nan << ' ' << -nan; > + out << std::showpos; > + out << ' ' << nan << ' ' << -nan; > + VERIFY( out.str() == " nan -nan NAN -NAN NAN -NAN +NAN -NAN" ); > +} > + > +void > +test_inf() > +{ > + std::ostringstream out; > + double inf = std::numeric_limits<double>::infinity(); > + out << std::fixed; > + out << ' ' << inf << ' ' << -inf; > + out << std::uppercase; > + out << ' ' << inf << ' ' << -inf; > + out << std::showpoint; > + out << ' ' << inf << ' ' << -inf; > + out << std::showpos; > + out << ' ' << inf << ' ' << -inf; > + VERIFY( out.str() == " inf -inf INF -INF INF -INF +INF -INF" ); > +} > + > +int main() > +{ > + test_nan(); > + test_inf(); > +} > -- > 2.45.2 >
diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc index fa469b1b872..02f53fd5ec1 100644 --- a/libstdc++-v3/src/c++98/locale_facets.cc +++ b/libstdc++-v3/src/c++98/locale_facets.cc @@ -84,17 +84,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__mod) *__fptr++ = __mod; - // [22.2.2.2.2] Table 58 + // C++11 [facet.num.put.virtuals] Table 88 + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4084. std::fixed ignores std::uppercase + bool __upper = __flags & ios_base::uppercase; if (__fltfield == ios_base::fixed) - *__fptr++ = 'f'; + *__fptr++ = __upper ? 'F' : 'f'; else if (__fltfield == ios_base::scientific) - *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e'; + *__fptr++ = __upper ? 'E' : 'e'; #if _GLIBCXX_USE_C99_STDIO else if (__fltfield == (ios_base::fixed | ios_base::scientific)) - *__fptr++ = (__flags & ios_base::uppercase) ? 'A' : 'a'; + *__fptr++ = __upper ? 'A' : 'a'; #endif else - *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g'; + *__fptr++ = __upper ? 'G' : 'g'; *__fptr = '\0'; } diff --git a/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc b/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc new file mode 100644 index 00000000000..b7c7da11f86 --- /dev/null +++ b/libstdc++-v3/testsuite/22_locale/num_put/put/char/lwg4084.cc @@ -0,0 +1,46 @@ +// { dg-do run } +// LWG 4084. std::fixed ignores std::uppercase +// PR libstdc++/114862 std::uppercase not applying to nan's and inf's + +#include <sstream> +#include <limits> +#include <iomanip> +#include <testsuite_hooks.h> + +void +test_nan() +{ + std::ostringstream out; + double nan = std::numeric_limits<double>::quiet_NaN(); + out << std::fixed; + out << ' ' << nan << ' ' << -nan; + out << std::uppercase; + out << ' ' << nan << ' ' << -nan; + out << std::showpoint; + out << ' ' << nan << ' ' << -nan; + out << std::showpos; + out << ' ' << nan << ' ' << -nan; + VERIFY( out.str() == " nan -nan NAN -NAN NAN -NAN +NAN -NAN" ); +} + +void +test_inf() +{ + std::ostringstream out; + double inf = std::numeric_limits<double>::infinity(); + out << std::fixed; + out << ' ' << inf << ' ' << -inf; + out << std::uppercase; + out << ' ' << inf << ' ' << -inf; + out << std::showpoint; + out << ' ' << inf << ' ' << -inf; + out << std::showpos; + out << ' ' << inf << ' ' << -inf; + VERIFY( out.str() == " inf -inf INF -INF INF -INF +INF -INF" ); +} + +int main() +{ + test_nan(); + test_inf(); +}