From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from us-smtp-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [207.211.31.120]) by sourceware.org (Postfix) with ESMTP id 18FCF3851C3B for ; Thu, 20 Aug 2020 18:44:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 18FCF3851C3B Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-35-xjuDw-iWOVSgZTNWSNW4qw-1; Thu, 20 Aug 2020 14:44:18 -0400 X-MC-Unique: xjuDw-iWOVSgZTNWSNW4qw-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id AE7AC8030A3; Thu, 20 Aug 2020 18:44:17 +0000 (UTC) Received: from localhost (unknown [10.33.36.61]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5B20061177; Thu, 20 Aug 2020 18:44:17 +0000 (UTC) Date: Thu, 20 Aug 2020 19:44:16 +0100 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: Re: [committed] libstdc++: Make __int128 meet integer-class requirements [PR 96042] Message-ID: <20200820184416.GP3400@redhat.com> References: <20200819160004.GA11512@redhat.com> <20200819193640.GL3400@redhat.com> MIME-Version: 1.0 In-Reply-To: <20200819193640.GL3400@redhat.com> X-Clacks-Overhead: GNU Terry Pratchett X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Mimecast-Spam-Score: 0.001 X-Mimecast-Originator: redhat.com Content-Type: multipart/mixed; boundary="yZxAaITavNk3ADw/" Content-Disposition: inline X-Spam-Status: No, score=-14.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=unavailable autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 20 Aug 2020 18:44:23 -0000 --yZxAaITavNk3ADw/ Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline On 19/08/20 20:36 +0100, Jonathan Wakely wrote: >On 19/08/20 17:00 +0100, Jonathan Wakely wrote: >>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): >> Define. >> * testsuite/std/ranges/iota/96042.cc: New test. > >The attached patch is another change needed to support __int128 as an >integer-like type in strict mode. And one more piece of __int128 support. Tested x86_64-linux, -m32 and -m64. Committed to trunk. I'll backport this to gcc-10 too. --yZxAaITavNk3ADw/ Content-Type: text/x-patch; charset=us-ascii Content-Disposition: attachment; filename="patch.txt" commit 5e9ad288eb6fb366142b166e7985d16727b398e1 Author: Jonathan Wakely Date: Thu Aug 20 19:41:15 2020 libstdc++: Make incrementable<__int128> satisfied in strict mode This adds specializations of std::incrementable_traits so that 128-bit integers are always considered incrementable (and therefore usable with std::ranges::iota_view) even when they don't satisfy std::integral. libstdc++-v3/ChangeLog: * include/bits/iterator_concepts.h [__STRICT_ANSI__] (incrementable_traits<__int128>): Define specialization. (incrementable_traits): Likewise. * testsuite/std/ranges/iota/96042.cc: Test iota_view with __int128. diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index 5033f2bddc3..bd6660c5f22 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -173,6 +173,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION = make_signed_t() - std::declval<_Tp>())>; }; +#if defined __STRICT_ANSI__ && defined __SIZEOF_INT128__ + // __int128 is incrementable even if !integral<__int128> + template<> + struct incrementable_traits<__int128> + { using difference_type = __int128; }; + + template<> + struct incrementable_traits + { using difference_type = __int128; }; +#endif + namespace __detail { // An iterator such that iterator_traits<_Iter> names a specialization diff --git a/libstdc++-v3/testsuite/std/ranges/iota/96042.cc b/libstdc++-v3/testsuite/std/ranges/iota/96042.cc index 6f5c8f61fd2..911663bc413 100644 --- a/libstdc++-v3/testsuite/std/ranges/iota/96042.cc +++ b/libstdc++-v3/testsuite/std/ranges/iota/96042.cc @@ -24,8 +24,13 @@ void test01() { // PR libstdc++/96042 - using V = std::ranges::iota_view; + using V = std::ranges::iota_view; + + // In strict -std=c++20 mode there is no integer wider than long long, + // so V's difference type is an integer-class type, [iterator.concept.winc]. + // In practice this is either __int128 or __detail::__max_diff_type. using D = std::ranges::range_difference_t; + // Ensure that numeric_limits is correctly specialized for the type. using L = std::numeric_limits; static_assert( L::is_specialized ); static_assert( L::is_signed ); @@ -37,3 +42,24 @@ test01() static_assert( L::max() == ~L::min() ); static_assert( L::lowest() == L::min() ); } + +#ifdef __SIZEOF_INT128__ +void +test02() +{ + // When the target supports __int128 it can be used in iota_view + // even in strict mode where !integral<__int128>. + using V = std::ranges::iota_view<__int128, __int128>; + using D = std::ranges::range_difference_t; // __detail::__max_diff_type + using L = std::numeric_limits; + 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::digits ); + static_assert( L::digits10 == static_cast(L::digits * 0.30103) ); + static_assert( L::min() == (D(1) << L::digits) ); + static_assert( L::max() == ~L::min() ); + static_assert( L::lowest() == L::min() ); +} +#endif --yZxAaITavNk3ADw/--