From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2181) id 5FCA6385BF99; Mon, 12 Apr 2021 14:59:43 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5FCA6385BF99 MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Jonathan Wakely To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc r10-9698] libstdc++: Fix std::indirectly_readable ambiguity [LWG 3446] X-Act-Checkin: gcc X-Git-Author: Jonathan Wakely X-Git-Refname: refs/heads/releases/gcc-10 X-Git-Oldrev: e976dc67ac5b0f6e9ea5e7e0e4f99c40e5abcd28 X-Git-Newrev: 32a859531e854382c18abf0b14a306d83f793eb5 Message-Id: <20210412145943.5FCA6385BF99@sourceware.org> Date: Mon, 12 Apr 2021 14:59:43 +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: Mon, 12 Apr 2021 14:59:43 -0000 https://gcc.gnu.org/g:32a859531e854382c18abf0b14a306d83f793eb5 commit r10-9698-g32a859531e854382c18abf0b14a306d83f793eb5 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. (cherry picked from commit 186aa6304570e15065f31482e9c27326a3a6679f) 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 e2ad37179be..4f118df6b02 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 );