Re: Implement N3642 - User-defined Literals for Standard Library Types

2013-06-01 Thread Ed Smith-Rowland

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

2013-06-01 Thread Paolo Carlini


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-05-31 Thread Daniel Krügler
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

2013-05-31 Thread Ed Smith-Rowland

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

2013-05-31 Thread 3dw4rd
 
 
 
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

2013-05-31 Thread Jonathan Wakely
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