From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1059) id DCCD83947C06; Fri, 28 Aug 2020 16:01:33 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DCCD83947C06 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1598630493; bh=XDPb3w5wQZvMBMpcQYaSulkeK9ZsVk14mv+8RkhfsZ4=; h=From:To:Subject:Date:From; b=dmmsawAyDOLJecVqFxxGQgSaeaTJ94Sp9FOI0lBpASFfjvshFL7XARvwmM113eJZY eATIIA/WNYbR5PLbSDV26kZEkddMiielRpF8lcK7XqUaUOjN9WgJue0nMjxKF8zC7H cn/e6V9Pd2QfNBRWFVDC8Flm0zWG1+RSI4RAgiU8= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Nathan Sidwell To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc/devel/c++-modules] libstdc++: Fix std::indirectly_readable ambiguity [LWG 3446] X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/devel/c++-modules X-Git-Oldrev: a0e6f05d26d286f5a73007e425b109f0d327e15f X-Git-Newrev: 186aa6304570e15065f31482e9c27326a3a6679f Message-Id: <20200828160133.DCCD83947C06@sourceware.org> Date: Fri, 28 Aug 2020 16:01:33 +0000 (GMT) X-BeenThere: libstdc++-cvs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libstdc++-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 28 Aug 2020 16:01:34 -0000 https://gcc.gnu.org/g:186aa6304570e15065f31482e9c27326a3a6679f commit 186aa6304570e15065f31482e9c27326a3a6679f Author: Jonathan Wakely Date: Mon Aug 24 16:18:31 2020 +0100 libstdc++: Fix std::indirectly_readable ambiguity [LWG 3446] This implements the proposed resolution of LWG 3446. I'm also adding another new constrained specialization which isn't proposed by 3446, to resolve the ambiguity when a type has both value_type and element_type but denoting different types. libstdc++-v3/ChangeLog: * include/bits/iterator_concepts.h (indirectly_readable): Add partial specializations to resolve ambiguities (LWG 3446). * testsuite/24_iterators/associated_types/readable.traits.cc: Check types with both value_type and element_type. Diff: --- libstdc++-v3/include/bits/iterator_concepts.h | 30 ++++++++++++++++++++-- .../associated_types/readable.traits.cc | 26 +++++++++++++++++++ 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/include/bits/iterator_concepts.h b/libstdc++-v3/include/bits/iterator_concepts.h index bd6660c5f22..a568f2ab825 100644 --- a/libstdc++-v3/include/bits/iterator_concepts.h +++ b/libstdc++-v3/include/bits/iterator_concepts.h @@ -220,6 +220,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template requires is_object_v<_Tp> struct __cond_value_type<_Tp> { using value_type = remove_cv_t<_Tp>; }; + + template + concept __has_member_value_type + = requires { typename _Tp::value_type; }; + + template + concept __has_member_element_type + = requires { typename _Tp::element_type; }; + } // namespace __detail template struct indirectly_readable_traits { }; @@ -238,16 +247,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : indirectly_readable_traits<_Iter> { }; - template requires requires { typename _Tp::value_type; } + template<__detail::__has_member_value_type _Tp> struct indirectly_readable_traits<_Tp> : __detail::__cond_value_type { }; - template requires requires { typename _Tp::element_type; } + template<__detail::__has_member_element_type _Tp> struct indirectly_readable_traits<_Tp> : __detail::__cond_value_type { }; + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3446. indirectly_readable_traits ambiguity for types with both [...] + template<__detail::__has_member_value_type _Tp> + requires __detail::__has_member_element_type<_Tp> + && same_as, + remove_cv_t> + struct indirectly_readable_traits<_Tp> + : __detail::__cond_value_type + { }; + + // LWG 3446 doesn't add this, but it's needed for the case where + // value_type and element_type are both present, but not the same type. + template<__detail::__has_member_value_type _Tp> + requires __detail::__has_member_element_type<_Tp> + struct indirectly_readable_traits<_Tp> + { }; + namespace __detail { template diff --git a/libstdc++-v3/testsuite/24_iterators/associated_types/readable.traits.cc b/libstdc++-v3/testsuite/24_iterators/associated_types/readable.traits.cc index b503b0cdc1e..3c9c3927153 100644 --- a/libstdc++-v3/testsuite/24_iterators/associated_types/readable.traits.cc +++ b/libstdc++-v3/testsuite/24_iterators/associated_types/readable.traits.cc @@ -141,3 +141,29 @@ struct J // iterator_traits matches constrained specialization in the library, // so use its value_type. static_assert( check_alias ); + +struct I2 +{ + using element_type = int; +}; +// iterator_traits is not specialized, and no standard specialization +// matches, so use indirectly_readable_traits. +static_assert( check_alias::value_type> ); + +// LWG 3446 +struct I3 +{ + using value_type = long; + using element_type = const long; +}; +// iterator_traits is not specialized, and no standard specialization +// matches, so use indirectly_readable_traits. +static_assert( check_alias::value_type> ); + +// Correction to LWG 3446 +struct I4 +{ + using value_type = int; + using element_type = long; +}; +static_assert( ! has_alias );