[PATCH 3/3] libstdc++: Implement C++20 range adaptors
Stephan Bergmann
sbergman@redhat.com
Tue Feb 18 07:31:00 GMT 2020
On 18/02/2020 02:20, Patrick Palka wrote:
> On Mon, 17 Feb 2020, Stephan Bergmann wrote:
>> On 04/02/2020 03:07, Patrick Palka wrote:
>>> This patch implements [range.adaptors]. It also includes the changes from
>>> P3280
>>> and P3278 and P3323, without which many standard examples won't work.
>>
>> I see that with this
>> <https://gcc.gnu.org/git/gitweb.cgi?p=gcc.git;a=commit;h=cba9ef069e58eac00f30489d3ef21390caee6e45>
>> "libstdc++: Implement C++20 range adaptors", compiling <ranges> with recent
>> Clang trunk (which appears to mostly implement C++20 concepts now) in
>> -std=c++2a mode fails as below (besides also failing due to some "missing"
>> typenames, where Clang apparently doesn't yet implement P0634R3). And I'm not
>> sure which of Clang vs. GCC is right here.
>>
>> The failure is
>>
>>> gcc/trunk/inst/include/c++/10.0.1/ranges:1512:47: error: ambiguous deduction
>>> for template arguments of '_RangeAdaptor'
>>> inline constexpr __adaptor::_RangeAdaptor filter
>>> ^
>>> gcc/trunk/inst/include/c++/10.0.1/ranges:1073:2: note: candidate function
>>> [with _Callable = std::ranges::views::(lambda at
>>> gcc/trunk/inst/include/c++/10.0.1/ranges:1513:9)]
>>> _RangeAdaptor(const _Callable& = {})
>>> ^
>>> gcc/trunk/inst/include/c++/10.0.1/ranges:1078:2: note: candidate function
>>> [with _Callable = std::ranges::views::(lambda at
>>> gcc/trunk/inst/include/c++/10.0.1/ranges:1513:9)]
>>> _RangeAdaptor(_Callable __callable)
>>> ^
>>
>> and a stripped-down reproducer is
>>
>>> template<typename T> struct S {
>>> S(T const &) requires true;
>>> S(T) requires false;
>>> };
>>> S s = 0;
>>
>> (Clang accepts this when the last line is replaced with
>>
>>> S<int> s = 0;
>>
>> and thus no class template argument deduction needs to be done.)
>>
>> I think what is relevant here is [over.match.class.deduct]/1 in the current
>> spec, which specifies a helper set of hypothetical function templates based on
>> a class' constructors for class template argument deduction. It details the
>> function templates' template parameters, function parameters, and return
>> types, but does not mention requires-clauses. From my superficial
>> understanding of concepts and class template argument deduction it would thus
>> look like the constructors' requires-clauses should indeed not be taken into
>> account here?
>
> Thanks for letting me know about this issue. That would be my
> interpretation of the spec, too. Maybe someone else could shed light on
> this question?
>
> The following patch simplifies _RangeAdaptor's constructors to no longer
> need to be constrained and should resolve the deduction ambiguity error
> reported by Clang? Unfortunately the patch triggers an ICE in GCC,
> which I'll look into tomorrow.
Thanks, I can confirm that patch works fine with Clang.
Btw, the "missing" typenames for Clang I mentioned above would be fixed
with the following patch. I don't know whether you would want to do
that, as technically the current C++20-only code is fine, but here it is
anyway:
> diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
> index 970e904bddd..c487dd612c2 100644
> --- a/libstdc++-v3/include/std/ranges
> +++ b/libstdc++-v3/include/std/ranges
> @@ -1326,7 +1326,7 @@ namespace views
> static constexpr auto
> _S_iter_cat()
> {
> - using _Cat = iterator_traits<iterator_t<_Vp>>::iterator_category;
> + using _Cat = typename iterator_traits<iterator_t<_Vp>>::iterator_category;
> if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
> return bidirectional_iterator_tag{};
> else if constexpr (derived_from<_Cat, forward_iterator_tag>)
> @@ -1549,7 +1549,7 @@ namespace views
> static constexpr auto
> _S_iter_cat()
> {
> - using _Cat = iterator_traits<iterator_t<_Base>>::iterator_category;
> + using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
> if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
> return random_access_iterator_tag{};
> else
> @@ -2294,9 +2294,9 @@ namespace views
> _S_iter_cat()
> {
> using _OuterCat
> - = iterator_traits<iterator_t<_Base>>::iterator_category;
> + = typename iterator_traits<iterator_t<_Base>>::iterator_category;
> using _InnerCat
> - = iterator_traits<iterator_t<range_reference_t<_Base>>>
> + = typename iterator_traits<iterator_t<range_reference_t<_Base>>>
> ::iterator_category;
> if constexpr (_S_ref_is_glvalue
> && derived_from<_OuterCat, bidirectional_iterator_tag>
> @@ -2765,7 +2765,7 @@ namespace views
> static constexpr auto
> _S_iter_cat()
> {
> - using _Cat = iterator_traits<iterator_t<_Base>>::iterator_category;
> + using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
> if constexpr (derived_from<_Cat, forward_iterator_tag>)
> return forward_iterator_tag{};
> else
More information about the Libstdc++
mailing list