From patchwork Mon Oct 6 15:56:15 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 396861 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C4AFE1400DD for ; Tue, 7 Oct 2014 02:56:32 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:content-transfer-encoding:in-reply-to; q=dns; s= default; b=fbiRR07kKQqsv/oCEgphEt9RgPBzFwHDZgcAGQUfmOr4j/WGr+Evm csnhLl/xZVGVTv1IuGqazdox1a3c9Kk7nToVw/E1CCnvJXYkcvdlM9SN/VvvF89R 3TApz3PLzuOpQ8Pff8WV/dnEDA3CDenyH/TaFYqG2k6t3yYBzBOXWw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:references:mime-version :content-type:content-transfer-encoding:in-reply-to; s=default; bh=K019Qsn7V1g/RVNtOe42Q+AqFAU=; b=YHza8jCWCoNF6q7/+BjIuuWQ3oEY C+XZqKVfzTQpWAOqw9fK033zR/ZZIhOlvynjYOt3HW5/N5amxuTbNaKRlUTDAGl9 POOz5xnK3JCLRqgbKI/9GZBxLSlyhV6NkdTuS0+vokcaSMJuLtf+arb+Tm2xBJKJ pCOVEpW2GZRSsj8= Received: (qmail 27181 invoked by alias); 6 Oct 2014 15:56:24 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 27139 invoked by uid 89); 6 Oct 2014 15:56:24 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.1 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 06 Oct 2014 15:56:21 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s96FuHe2019668 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Mon, 6 Oct 2014 11:56:17 -0400 Received: from localhost (ovpn-116-121.ams2.redhat.com [10.36.116.121]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s96FuG78018952; Mon, 6 Oct 2014 11:56:16 -0400 Date: Mon, 6 Oct 2014 16:56:15 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: =?iso-8859-1?Q?R=FCdiger?= Sonderfeld , Luke Allardyce Subject: Re: [PATCH v2] libstdc++: Add hexfloat/defaultfloat io manipulators. Message-ID: <20141006155615.GN4197@redhat.com> References: <20140327133723.GA13599@redhat.com> <1901588.qodTErPe42@descartes> <20140327162714.GA13192@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.23 (2014-03-12) On 28/03/14 08:56 +0900, Luke Allardyce wrote: >It looks like the new standard also requires the precision to be >ignored for hexfloat > >>For conversion from a floating-point type, if floatfield != (ios_base::fixed | ios_base:: scientific), str.precision() is specified as precision in the conversion specification. Otherwise, no precision is specified. I've made this change and adjusted the test so that it doesn't make any assumptions about the exact format of hexadecimal float output, as it's unspecified whether you get e.g. 0x1.ep+3 or 0xfp+0 for 15. As Luke pointed out, this changes the behaviour of some valid C++03 programs, but I think that's the right thing to do in this case. I'll document that in the release notes. Tested x86_64-linux, committed to trunk. commit 7090c2fca0e3858ea527b66a1eb44fd504f1ba4e Author: Jonathan Wakely Date: Mon Sep 22 23:10:54 2014 +0100 2014-10-06 RĂ¼diger Sonderfeld Jonathan Wakely PR libstdc++/59987 * doc/xml/manual/status_cxx2011.xml: Remove hexfloat from notes. * doc/html/manual/status.html: Regenerate. * include/bits/ios_base.h (hexfloat): New function. (defaultfloat): New function. * src/c++98/locale_facets.cc (__num_base::_S_format_float): Support hexadecimal floating point format. * testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc: New file. diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml index 5b36556..108de36 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml @@ -2131,7 +2131,6 @@ particular release. Missing io_errc and iostream_category. ios_base::failure is not derived from system_error. - Missing ios_base::hexfloat. diff --git a/libstdc++-v3/include/bits/ios_base.h b/libstdc++-v3/include/bits/ios_base.h index fb448fd..5e33b81 100644 --- a/libstdc++-v3/include/bits/ios_base.h +++ b/libstdc++-v3/include/bits/ios_base.h @@ -984,6 +984,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __base; } +#if __cplusplus >= 201103L + // New C++11 floatfield manipulators + + /// Calls + /// base.setf(ios_base::fixed|ios_base::scientific, ios_base::floatfield) + inline ios_base& + hexfloat(ios_base& __base) + { + __base.setf(ios_base::fixed | ios_base::scientific, ios_base::floatfield); + return __base; + } + + /// Calls @c base.unsetf(ios_base::floatfield) + inline ios_base& + defaultfloat(ios_base& __base) + { + __base.unsetf(ios_base::floatfield); + return __base; + } +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/src/c++98/locale_facets.cc b/libstdc++-v3/src/c++98/locale_facets.cc index 3669acb..7ed04e6 100644 --- a/libstdc++-v3/src/c++98/locale_facets.cc +++ b/libstdc++-v3/src/c++98/locale_facets.cc @@ -69,19 +69,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION if (__flags & ios_base::showpoint) *__fptr++ = '#'; - // As per DR 231: _always_, not only when - // __flags & ios_base::fixed || __prec > 0 - *__fptr++ = '.'; - *__fptr++ = '*'; + ios_base::fmtflags __fltfield = __flags & ios_base::floatfield; + + if (__fltfield != (ios_base::fixed | ios_base::scientific)) + { + // As per DR 231: not only when __flags & ios_base::fixed || __prec > 0 + *__fptr++ = '.'; + *__fptr++ = '*'; + } if (__mod) *__fptr++ = __mod; - ios_base::fmtflags __fltfield = __flags & ios_base::floatfield; // [22.2.2.2.2] Table 58 if (__fltfield == ios_base::fixed) *__fptr++ = 'f'; else if (__fltfield == ios_base::scientific) *__fptr++ = (__flags & ios_base::uppercase) ? 'E' : 'e'; +#ifdef _GLIBCXX_USE_C99 + else if (__fltfield == (ios_base::fixed | ios_base::scientific)) + *__fptr++ = (__flags & ios_base::uppercase) ? 'A' : 'a'; +#endif else *__fptr++ = (__flags & ios_base::uppercase) ? 'G' : 'g'; *__fptr = '\0'; diff --git a/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc new file mode 100644 index 0000000..485a485 --- /dev/null +++ b/libstdc++-v3/testsuite/27_io/basic_ostream/inserters_arithmetic/char/hexfloat.cc @@ -0,0 +1,152 @@ +// { dg-options "-std=gnu++11" } + +// 2014-03-27 RĂ¼diger Sonderfeld +// test the hexadecimal floating point inserters (facet num_put) + +// Copyright (C) 2014 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 +// . + +#include +#include +#include +#include + +#ifndef _GLIBCXX_ASSERT +# define TEST_NUMPUT_VERBOSE 1 +#endif + +#ifdef TEST_NUMPUT_VERBOSE +# include +#endif + +using namespace std; + +void +test01() +{ + ostringstream os; + double d = 272.; // 0x1.1p+8; +#ifdef TEST_NUMPUT_VERBOSE + cout << os.precision() << endl; +#endif + os << hexfloat << setprecision(1); + os << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && std::stod(os.str()) == d ); + VERIFY( os.str().substr(0, 2) == "0x" ); + VERIFY( os.str().find('p') != std::string::npos ); + + os.str(""); + os << uppercase << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && std::stod(os.str()) == d ); + VERIFY( os.str().substr(0, 2) == "0X" ); + VERIFY( os.str().find('P') != std::string::npos ); + + os << nouppercase; + os.str(""); + os << defaultfloat << setprecision(6); + os << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && os.str() == "272" ); + + os.str(""); + d = 15.; //0x1.ep+3; + os << hexfloat << setprecision(1); + os << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && std::stod(os.str()) == d ); + os.str(""); + os << uppercase << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && std::stod(os.str()) == d ); + os << nouppercase; + os.str(""); + os << defaultfloat << setprecision(6); + os << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && os.str() == "15" ); +} + +void +test02() +{ + ostringstream os; + long double d = 272.L; // 0x1.1p+8L; + os << hexfloat << setprecision(1); + os << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && std::stold(os.str()) == d ); + os.str(""); + os << uppercase << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && std::stold(os.str()) == d ); + os << nouppercase; + os.str(""); + os << defaultfloat << setprecision(6); + os << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && os.str() == "272" ); + + os.str(""); + os << hexfloat << setprecision(1); + d = 15.; //0x1.ep+3; + os << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && std::stold(os.str()) == d ); + os.str(""); + os << uppercase << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && std::stold(os.str()) == d ); + os << nouppercase; + os.str(""); + os << defaultfloat << setprecision(6); + os << d; +#ifdef TEST_NUMPUT_VERBOSE + cout << "got: " << os.str() << endl; +#endif + VERIFY( os && os.str() == "15" ); +} + +int +main() +{ + test01(); + test02(); +}