Patchwork [v3] is_modulo

login
register
mail settings
Submitter Marc Glisse
Date April 28, 2012, 10:41 p.m.
Message ID <alpine.DEB.2.02.1204290022390.2641@laptop-mg.saclay.inria.fr>
Download mbox | patch
Permalink /patch/155701/
State New
Headers show

Comments

Marc Glisse - April 28, 2012, 10:41 p.m.
Hello,

the attached follows the precisions on the definition of is_modulo in 
DR 612. I believe this is what the values always should have been, so I 
didn't make the change conditional to C++11.

PR 22200 can remain open if people want to discuss the interaction with 
-fwrapv, but false is the safe value.

I ran the testsuite, to make sure there wasn't a huge typo that would 
prevent the file from compiling, and the only failure was the usual 
22_locale/time_get/get_date/wchar_t/4.cc.

2012-04-29  Marc Glisse  <marc.glisse@inria.fr>

 	PR libstdc++/22200
 	* include/std/limits (numeric_limits<>::is_modulo): false for
 	signed types.
Gabriel Dos Reis - April 28, 2012, 11:29 p.m.
On Sat, Apr 28, 2012 at 5:41 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> Hello,
>
> the attached follows the precisions on the definition of is_modulo in DR
> 612. I believe this is what the values always should have been, so I didn't
> make the change conditional to C++11.

Thanks for the patch.
I think  'char' shouldn't be considered modulo  even if
-funsigned-char -- I will bring this to LWG attention.

>
> PR 22200 can remain open if people want to discuss the interaction with
> -fwrapv, but false is the safe value.

I believe the interaction with -fwrapv is an interesting one.

>
> I ran the testsuite, to make sure there wasn't a huge typo that would
> prevent the file from compiling, and the only failure was the usual
> 22_locale/time_get/get_date/wchar_t/4.cc.

OK.
>
> 2012-04-29  Marc Glisse  <marc.glisse@inria.fr>
>
>        PR libstdc++/22200
>        * include/std/limits (numeric_limits<>::is_modulo): false for
>        signed types.
>
> --
> Marc Glisse
Marc Glisse - April 28, 2012, 11:45 p.m.
On Sat, 28 Apr 2012, Gabriel Dos Reis wrote:

> On Sat, Apr 28, 2012 at 5:41 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
>> Hello,
>>
>> the attached follows the precisions on the definition of is_modulo in DR
>> 612. I believe this is what the values always should have been, so I didn't
>> make the change conditional to C++11.
>
> Thanks for the patch.
> I think  'char' shouldn't be considered modulo  even if
> -funsigned-char -- I will bring this to LWG attention.

Why not? If an implementation decides to guarantee that the arithmetic on 
a type is modular, it should advertise it through this trait, I don't see 
anything wrong about that. Well, doing arithmetic on char may not be the 
best idea, but still... Actually, if you are going to bring this up in 
LWG, let's not discuss that here.

> OK.

Note that I can't commit, you'll have to do it, sorry...
Gabriel Dos Reis - April 29, 2012, 12:32 p.m.
On Sat, Apr 28, 2012 at 6:45 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Sat, 28 Apr 2012, Gabriel Dos Reis wrote:
>
>> On Sat, Apr 28, 2012 at 5:41 PM, Marc Glisse <marc.glisse@inria.fr> wrote:
>>>
>>> Hello,
>>>
>>> the attached follows the precisions on the definition of is_modulo in DR
>>> 612. I believe this is what the values always should have been, so I
>>> didn't
>>> make the change conditional to C++11.
>>
>>
>> Thanks for the patch.
>> I think  'char' shouldn't be considered modulo  even if
>> -funsigned-char -- I will bring this to LWG attention.
>
>
> Why not? If an implementation decides to guarantee that the arithmetic on a
> type is modular, it should advertise it through this trait, I don't see
> anything wrong about that. Well, doing arithmetic on char may not be the
> best idea, but still...

(1) char really is a character type, it is an 'accident' that it is
classified as arithmetic type.
(2) there is no arithmetic operation on char: the arithmetic is done
on a different type
      and the result clamped back to char.

> Actually, if you are going to bring this up in LWG,
> let's not discuss that here.

Exactly.

>
>> OK.
>
>
> Note that I can't commit, you'll have to do it, sorry...
>
> --
> Marc Glisse

Patch

Index: include/std/limits

===================================================================
--- include/std/limits	(revision 186932)

+++ include/std/limits	(working copy)

@@ -268,14 +268,17 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

     /** <em>True if the set of values representable by the type is
 	finite.  All built-in types are bounded, this member would be
 	false for arbitrary precision types.</em> [18.2.1.2]/54  */
     static _GLIBCXX_USE_CONSTEXPR bool is_bounded = false;
 
-    /** True if the type is @e modulo, that is, if it is possible to add two

-	positive numbers and have a result that wraps around to a third number

-	that is less.  Typically false for floating types, true for unsigned

-	integers, and true for signed integers.  */

+    /** True if the type is @e modulo. A type is modulo if, for any

+	operation involving +, -, or * on values of that type whose

+	result would fall outside the range [min(),max()], the value

+	returned differs from the true value by an integer multiple of

+	max() - min() + 1. On most machines, this is false for floating

+	types, true for unsigned integers, and true for signed integers.

+	See PR22200 about signed integers.  */

     static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;
 
     /** True if trapping is implemented for this type.  */
     static _GLIBCXX_USE_CONSTEXPR bool traps = false;
 
@@ -492,11 +495,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       static _GLIBCXX_CONSTEXPR char 
       denorm_min() _GLIBCXX_USE_NOEXCEPT { return static_cast<char>(0); }
 
       static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
       static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = !is_signed;

 
       static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
       static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
       static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 
        = round_toward_zero;
@@ -562,11 +565,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       denorm_min() _GLIBCXX_USE_NOEXCEPT
       { return static_cast<signed char>(0); }
 
       static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
       static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

 
       static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
       static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
       static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 
        = round_toward_zero;
@@ -703,11 +706,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       static _GLIBCXX_CONSTEXPR wchar_t 
       denorm_min() _GLIBCXX_USE_NOEXCEPT { return wchar_t(); }
 
       static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
       static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = !is_signed;

 
       static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
       static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
       static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 
        = round_toward_zero;
@@ -766,11 +769,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       static constexpr char16_t 
       denorm_min() noexcept { return char16_t(); }
 
       static constexpr bool is_iec559 = false;
       static constexpr bool is_bounded = true;
-      static constexpr bool is_modulo = true;

+      static constexpr bool is_modulo = !is_signed;

 
       static constexpr bool traps = __glibcxx_integral_traps;
       static constexpr bool tinyness_before = false;
       static constexpr float_round_style round_style = round_toward_zero;
     };
@@ -827,11 +830,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       static constexpr char32_t 
       denorm_min() noexcept { return char32_t(); }
 
       static constexpr bool is_iec559 = false;
       static constexpr bool is_bounded = true;
-      static constexpr bool is_modulo = true;

+      static constexpr bool is_modulo = !is_signed;

 
       static constexpr bool traps = __glibcxx_integral_traps;
       static constexpr bool tinyness_before = false;
       static constexpr float_round_style round_style = round_toward_zero;
     };
@@ -894,11 +897,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       static _GLIBCXX_CONSTEXPR short 
       denorm_min() _GLIBCXX_USE_NOEXCEPT { return short(); }
 
       static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
       static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

 
       static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
       static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
       static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 
        = round_toward_zero;
@@ -1034,11 +1037,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       static _GLIBCXX_CONSTEXPR int 
       denorm_min() _GLIBCXX_USE_NOEXCEPT { return static_cast<int>(0); }
 
       static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
       static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

 
       static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
       static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
       static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 
        = round_toward_zero;
@@ -1173,11 +1176,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       static _GLIBCXX_CONSTEXPR long 
       denorm_min() _GLIBCXX_USE_NOEXCEPT { return static_cast<long>(0); }
 
       static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
       static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

 
       static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
       static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
       static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 
        = round_toward_zero;
@@ -1316,11 +1319,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       static _GLIBCXX_CONSTEXPR long long 
       denorm_min() _GLIBCXX_USE_NOEXCEPT { return static_cast<long long>(0); }
 
       static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
       static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

 
       static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
       static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
       static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 
        = round_toward_zero;
@@ -1463,11 +1466,11 @@  _GLIBCXX_BEGIN_NAMESPACE_VERSION

       denorm_min() _GLIBCXX_USE_NOEXCEPT
       { return static_cast<__int128>(0); }
 
       static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
       static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
-      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

+      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

 
       static _GLIBCXX_USE_CONSTEXPR bool traps
        = __glibcxx_integral_traps;
       static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
       static _GLIBCXX_USE_CONSTEXPR float_round_style round_style