From: Jonathan Wakely <jwakely@redhat.com>
To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org
Subject: [committed] libstdc++: Make __int128 meet integer-class requirements [PR 96042]
Date: Wed, 19 Aug 2020 17:00:04 +0100 [thread overview]
Message-ID: <20200819160004.GA11512@redhat.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1345 bytes --]
Because __int128 can be used as the difference type for iota_view, we
need to ensure that it meets the requirements of an integer-class type.
The requirements in [iterator.concept.winc] p10 include numeric_limits
being specialized and giving meaningful answers. Currently we only
specialize numeric_limits for non-standard integer types in non-strict
modes. However, nothing prevents us from defining an explicit
specialization for any implementation-defined type, so it doesn't matter
whether std::is_integral<__int128> is true or not.
This patch ensures that the numeric_limits specializations for signed
and unsigned __int128 are defined whenever __int128 is available. It
also makes the __numeric_traits and __int_limits helpers work for
__int128, via a new __gnu_cxx::__is_integer_nonstrict trait.
libstdc++-v3/ChangeLog:
PR libstdc++/96042
* include/ext/numeric_traits.h (__is_integer_nonstrict): New
trait which is true for 128-bit integers even in strict modes.
(__numeric_traits_integer, __numeric_traits): Use
__is_integer_nonstrict instead of __is_integer.
* include/std/limits [__STRICT_ANSI__ && __SIZEOF_INT128__]
(numeric_limits<__int128>, (numeric_limits<unsigned __int128>):
Define.
* testsuite/std/ranges/iota/96042.cc: New test.
Tested powerpc64le-linux. Committed to trunk.
I'll backport this to gcc-10 too.
[-- Attachment #2: patch.txt --]
[-- Type: text/plain, Size: 5971 bytes --]
commit 386fd16c551188e20d5b1684b7139e4269f9a739
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Wed Aug 19 16:27:25 2020
libstdc++: Make __int128 meet integer-class requirements [PR 96042]
Because __int128 can be used as the difference type for iota_view, we
need to ensure that it meets the requirements of an integer-class type.
The requirements in [iterator.concept.winc] p10 include numeric_limits
being specialized and giving meaningful answers. Currently we only
specialize numeric_limits for non-standard integer types in non-strict
modes. However, nothing prevents us from defining an explicit
specialization for any implementation-defined type, so it doesn't matter
whether std::is_integral<__int128> is true or not.
This patch ensures that the numeric_limits specializations for signed
and unsigned __int128 are defined whenever __int128 is available. It
also makes the __numeric_traits and __int_limits helpers work for
__int128, via a new __gnu_cxx::__is_integer_nonstrict trait.
libstdc++-v3/ChangeLog:
PR libstdc++/96042
* include/ext/numeric_traits.h (__is_integer_nonstrict): New
trait which is true for 128-bit integers even in strict modes.
(__numeric_traits_integer, __numeric_traits): Use
__is_integer_nonstrict instead of __is_integer.
* include/std/limits [__STRICT_ANSI__ && __SIZEOF_INT128__]
(numeric_limits<__int128>, (numeric_limits<unsigned __int128>):
Define.
* testsuite/std/ranges/iota/96042.cc: New test.
diff --git a/libstdc++-v3/include/ext/numeric_traits.h b/libstdc++-v3/include/ext/numeric_traits.h
index 69f286d7be7..585ecc0ba9f 100644
--- a/libstdc++-v3/include/ext/numeric_traits.h
+++ b/libstdc++-v3/include/ext/numeric_traits.h
@@ -51,11 +51,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
(__glibcxx_signed(_Tp) ? \
(((((_Tp)1 << (__glibcxx_digits(_Tp) - 1)) - 1) << 1) + 1) : ~(_Tp)0)
+ template<typename _Tp>
+ struct __is_integer_nonstrict
+ : public std::__is_integer<_Tp>
+ { };
+
+#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
+ // __is_integer<__int128> is false, but we still want to allow it here.
+ template<> struct __is_integer_nonstrict<__int128>
+ { enum { __value = 1 }; typedef std::__true_type __type; };
+
+ template<> struct __is_integer_nonstrict<unsigned __int128>
+ { enum { __value = 1 }; typedef std::__true_type __type; };
+#endif
+
template<typename _Value>
struct __numeric_traits_integer
{
#if __cplusplus >= 201103L
- static_assert(std::__is_integer<_Value>::__value,
+ static_assert(__is_integer_nonstrict<_Value>::__value,
"invalid specialization");
#endif
@@ -132,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Value>
struct __numeric_traits
- : public __conditional_type<std::__is_integer<_Value>::__value,
+ : public __conditional_type<__is_integer_nonstrict<_Value>::__value,
__numeric_traits_integer<_Value>,
__numeric_traits_floating<_Value> >::__type
{ };
diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits
index f5e403be727..20883ba6403 100644
--- a/libstdc++-v3/include/std/limits
+++ b/libstdc++-v3/include/std/limits
@@ -1477,8 +1477,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= round_toward_zero;
};
-#if !defined(__STRICT_ANSI__)
-
#define __INT_N(TYPE, BITSIZE, EXT, UEXT) \
template<> \
struct numeric_limits<TYPE> \
@@ -1632,6 +1630,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#define __INT_N_U201103(TYPE)
#endif
+#if !defined(__STRICT_ANSI__)
#ifdef __GLIBCXX_TYPE_INT_N_0
__INT_N(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0,
__INT_N_201103 (__GLIBCXX_TYPE_INT_N_0),
@@ -1653,11 +1652,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__INT_N_U201103 (__GLIBCXX_TYPE_INT_N_3))
#endif
+#elif defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
+ __INT_N(__int128, 128,
+ __INT_N_201103 (__int128),
+ __INT_N_U201103 (__int128))
+#endif
+
#undef __INT_N
#undef __INT_N_201103
#undef __INT_N_U201103
-#endif
/// numeric_limits<float> specialization.
template<>
diff --git a/libstdc++-v3/testsuite/std/ranges/iota/96042.cc b/libstdc++-v3/testsuite/std/ranges/iota/96042.cc
new file mode 100644
index 00000000000..6f5c8f61fd2
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/iota/96042.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2020 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
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=c++2a" }
+// { dg-do compile { target c++2a } }
+
+#include <ranges>
+
+void
+test01()
+{
+ // PR libstdc++/96042
+ using V = std::ranges::iota_view<long long, int>;
+ using D = std::ranges::range_difference_t<V>;
+ using L = std::numeric_limits<D>;
+ static_assert( L::is_specialized );
+ static_assert( L::is_signed );
+ static_assert( L::is_integer );
+ static_assert( L::is_exact );
+ static_assert( L::digits > std::numeric_limits<long long>::digits );
+ static_assert( L::digits10 == static_cast<int>(L::digits * 0.30103) );
+ static_assert( L::min() == (D(1) << L::digits) );
+ static_assert( L::max() == ~L::min() );
+ static_assert( L::lowest() == L::min() );
+}
next reply other threads:[~2020-08-19 16:00 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-19 16:00 Jonathan Wakely [this message]
2020-08-19 19:36 ` Jonathan Wakely
2020-08-20 18:44 ` Jonathan Wakely
2020-08-22 9:50 ` Marc Glisse
2020-08-22 12:13 ` Jonathan Wakely
2020-08-22 12:17 ` JeanHeyd Meneide
2020-08-22 12:32 ` Jonathan Wakely
2020-08-22 12:37 ` Jonathan Wakely
2020-08-22 15:00 ` Marc Glisse
2020-08-24 8:52 ` Jonathan Wakely
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200819160004.GA11512@redhat.com \
--to=jwakely@redhat.com \
--cc=gcc-patches@gcc.gnu.org \
--cc=libstdc++@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).