Re: Implement N3642 - User-defined Literals for Standard Library Types
Committed the following... 2013-05-30 Ed Smith-Rowland 3dw...@verizon.net Implement N3642 - User-defined Literals for Standard Library Types * include/bits/parse_numbers.h: New. * include/std/chrono: Add duration literal operators. * include/bits/basic_string.h: Add string literal operators. * include/Makefile.in: Add parse_numbers.h. * include/Makefile.am: Ditto. * testsuite/20_util/duration/literals/values.cc: New. * testsuite/20_util/duration/literals/types.cc: New. * testsuite/20_util/duration/requirements/typedefs_neg1.cc: Adjust. * testsuite/20_util/duration/requirements/typedefs_neg2.cc: Adjust. * testsuite/20_util/duration/requirements/typedefs_neg3.cc: Adjust. * testsuite/21_strings/basic_string/literals/values.cc: New. * testsuite/21_strings/basic_string/literals/types.cc: New. Index: include/bits/parse_numbers.h === --- include/bits/parse_numbers.h(revision 0) +++ include/bits/parse_numbers.h(working copy) @@ -0,0 +1,417 @@ +// Components for compile-time parsing of numbers -*- C++ -*- + +// Copyright (C) 2013 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 bits/parse_numbers.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{chrono} + */ + +#ifndef _PARSE_NUMBERS_H +#define _PARSE_NUMBERS_H 1 + +#pragma GCC system_header + +// From n3642.pdf except I added binary literals and digit separator '`'. + +#if __cplusplus 201103L + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace __parse_int { + + templateunsigned _Base, char _Dig +struct _Digit; + + templateunsigned _Base +struct _Digit_Base, '0' +{ + static constexpr bool valid{true}; + static constexpr unsigned value{0}; +}; + + templateunsigned _Base +struct _Digit_Base, '1' +{ + static constexpr bool valid{true}; + static constexpr unsigned value{1}; +}; + + templateunsigned _Base +struct _Digit_Base, '2' +{ + static_assert(_Base 2, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{2}; +}; + + templateunsigned _Base +struct _Digit_Base, '3' +{ + static_assert(_Base 3, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{3}; +}; + + templateunsigned _Base +struct _Digit_Base, '4' +{ + static_assert(_Base 4, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{4}; +}; + + templateunsigned _Base +struct _Digit_Base, '5' +{ + static_assert(_Base 5, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{5}; +}; + + templateunsigned _Base +struct _Digit_Base, '6' +{ + static_assert(_Base 6, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{6}; +}; + + templateunsigned _Base +struct _Digit_Base, '7' +{ + static_assert(_Base 7, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{7}; +}; + + templateunsigned _Base +struct _Digit_Base, '8' +{ + static_assert(_Base 8, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{8}; +}; + + templateunsigned _Base +struct _Digit_Base, '9' +{ + static_assert(_Base 9, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{9}; +}; + + templateunsigned _Base +struct _Digit_Base, 'a' +{ + static_assert(_Base 0xa, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{0xa}; +}; + + templateunsigned _Base +struct _Digit_Base,
Re: Implement N3642 - User-defined Literals for Standard Library Types
Hi, Ed Smith-Rowland 3dw...@verizon.net ha scritto: Committed the following... Looks like great work, thanks! I'm still in vacations, and barely reading email on a small screen, just wanted to point out that apparently the patch has a few redundant inline preceding constexpr. Could you please double check? Thanks! Paolo
Re: Implement N3642 - User-defined Literals for Standard Library Types
2013/5/31 Ed Smith-Rowland 3dw...@verizon.net: Greetings, This patch implements N3642 - User-defined literals for std::chrono::duration and std::basic_string and N3660 - User-defined literals for std::complex. N3660 was rejected during the Bristol meeting, the main reason being the ugliness of the complex-float literal and giving it some time to find a possible sore language solution. Is there still the idea to add this now? - Daniel
Re: Implement N3642 - User-defined Literals for Standard Library Types
On 05/31/2013 10:41 AM, Daniel Krügler wrote: 2013/5/31 Ed Smith-Rowland 3dw...@verizon.net: Greetings, This patch implements N3642 - User-defined literals for std::chrono::duration and std::basic_string and N3660 - User-defined literals for std::complex. N3660 was rejected during the Bristol meeting, the main reason being the ugliness of the complex-float literal and giving it some time to find a possible sore language solution. Is there still the idea to add this now? - Daniel I would offer a modification of the lower-case rule for standard literal operators (I know this is bikeshed but I think such things are important and obviously prevent ideas from being adopted). I would say: 1. Put the precision first in upper case. As a matter of style I prefer 123456L to 123456l for normal literals anyway. Also, the precision snuggles next to the number - then you modify it. That seems logical to me. Also, if we involve decimal in this someday, those literals *have* to be all caps (for the old literals). It seems using lower case precision indicators for decimal would be inconsistent. 2. Use lower case for the other characters except... 3. If the name derives from a proper name, such as SI unit Farad use capitals. This will make literal operators for units match SI and the expectation of users most likely to use such literals. For complex this gives us: std::complexfloat operator Fi(long double imag) noexcept; std::complexfloat operator Fi(unsigned long long imag) noexcept; std::complexdouble operator i(long double imag) noexcept; std::complexdouble operator i(unsigned long long imag) noexcept; std::complexlong double operator Li(long double imag) noexcept; std::complexlong double operator Li(unsigned long long imag) noexcept; This avoids the i_f, and seems more logical to me. For the issue at hand, I split the patch. Ed Index: include/bits/parse_numbers.h === --- include/bits/parse_numbers.h(revision 0) +++ include/bits/parse_numbers.h(working copy) @@ -0,0 +1,417 @@ +// Components for compile-time parsing of numbers -*- C++ -*- + +// Copyright (C) 2013 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 bits/parse_numbers.h + * This is an internal header file, included by other library headers. + * Do not attempt to use it directly. @headername{chrono} + */ + +#ifndef _PARSE_NUMBERS_H +#define _PARSE_NUMBERS_H 1 + +#pragma GCC system_header + +// From n3642.pdf except I added binary literals and digit separator '`'. + +#if __cplusplus 201103L + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +namespace __parse_int { + + templateunsigned _Base, char _Dig +struct _Digit; + + templateunsigned _Base +struct _Digit_Base, '0' +{ + static constexpr bool valid{true}; + static constexpr unsigned value{0}; +}; + + templateunsigned _Base +struct _Digit_Base, '1' +{ + static constexpr bool valid{true}; + static constexpr unsigned value{1}; +}; + + templateunsigned _Base +struct _Digit_Base, '2' +{ + static_assert(_Base 2, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{2}; +}; + + templateunsigned _Base +struct _Digit_Base, '3' +{ + static_assert(_Base 3, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{3}; +}; + + templateunsigned _Base +struct _Digit_Base, '4' +{ + static_assert(_Base 4, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{4}; +}; + + templateunsigned _Base +struct _Digit_Base, '5' +{ + static_assert(_Base 5, invalid digit); + static constexpr bool valid{true}; + static constexpr unsigned value{5}; +}; + + templateunsigned _Base +struct _Digit_Base, '6' +{ + static_assert(_Base
Re: Re: Implement N3642 - User-defined Literals for Standard Library Types
On 05/31/13, Ed Smith-Rowland3dw...@verizon.net wrote: ... 1. Put the precision first in upper case. As a matter of style I prefer 123456L to 123456l for normal literals anyway. Also, the precision snuggles next to the number - then you modify it. That seems logical to me. Also, if we involve decimal in this someday, those literals *have* to be all caps (for the old literals). It seems using lower case precision indicators for decimal would be inconsistent. I must withdraw the comment about decimal literals needing to be all caps. That's wrong. The letters need to be all uppercase *or* all lowercase. You can't have mixed case. I'll shut up now and post this somewhere else. Ed
Re: Implement N3642 - User-defined Literals for Standard Library Types
On 31 May 2013 15:15, Ed Smith-Rowland wrote: Greetings, This patch implements N3642 - User-defined literals for std::chrono::duration and std::basic_string and N3660 - User-defined literals for std::complex. Great, thanks! User-defined literals were separated into two papers because of some controversy about noexcept for complex literals. If desired, I could split the patch into two bits for the two proposals. OTOH, I'm pretty sure complex literals will make it in. I'm not so sure, and if they do they might use if as the suffix rather than i_f, so please split this patch so the non-complex parts can go in. I don't think you need to touch config/abi/pre/gnu.ver, al lthe new functions are inline and not exported from the library, so you don't need to version symbols that aren't in the library (in fact, you *can't* version symbols that aren't in the library!) It looks like the changes to existing headers could be simplified by not closing and reopening the namespace, i.e. instead of: namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION [...] _GLIBCXX_END_NAMESPACE_VERSION } // namespace +#if __cplusplus 201103L + +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + +inline namespace literals { +inline namespace string_literals { [...] Just put the new stuff inside the already open namespace, i.e. namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION [...] +#if __cplusplus 201103L + +inline namespace literals { +inline namespace string_literals { [...] +} } +#endif + _GLIBCXX_END_NAMESPACE_VERSION } // namespace