1 // Copyright (C) 2021 Free Software Foundation, Inc.
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do compile { target c++2a } }
21 // PR libstdc++/100577
25 namespace ranges
= std::ranges
;
26 namespace views
= std::ranges::views
;
31 // Verify adaptors are deemed to have simple extra arguments when appropriate.
32 using views::__adaptor::__adaptor_has_simple_extra_args
;
34 static_assert(__adaptor_has_simple_extra_args
<decltype(views::transform
), identity
>);
35 static_assert(__adaptor_has_simple_extra_args
<decltype(views::filter
), identity
>);
36 static_assert(__adaptor_has_simple_extra_args
<decltype(views::drop
), int>);
37 static_assert(__adaptor_has_simple_extra_args
<decltype(views::take
), int>);
38 static_assert(__adaptor_has_simple_extra_args
<decltype(views::take_while
), identity
>);
39 static_assert(__adaptor_has_simple_extra_args
<decltype(views::drop_while
), identity
>);
40 static_assert(__adaptor_has_simple_extra_args
<decltype(views::split
), std::string_view
>);
41 static_assert(__adaptor_has_simple_extra_args
<decltype(views::split
), char>);
42 static_assert(!__adaptor_has_simple_extra_args
<decltype(views::split
), std::string
>);
44 // Verify all adaptor closures except for views::split(pattern) have a simple
46 using views::__adaptor::__closure_has_simple_call_op
;
47 __closure_has_simple_call_op
auto a00
= views::all
;
48 __closure_has_simple_call_op
auto a01
= views::transform(std::identity
{});
49 __closure_has_simple_call_op
auto a02
= views::filter(std::identity
{});
50 __closure_has_simple_call_op
auto a03
= views::drop(42);
51 __closure_has_simple_call_op
auto a04
= views::take(42);
52 __closure_has_simple_call_op
auto a05
= views::take_while(std::identity
{});
53 __closure_has_simple_call_op
auto a06
= views::drop_while(std::identity
{});
54 __closure_has_simple_call_op
auto a07
= views::join
;
55 __closure_has_simple_call_op
auto a08
= views::common
;
56 __closure_has_simple_call_op
auto a09
= views::reverse
;
57 __closure_has_simple_call_op
auto a10
= views::keys
;
58 __closure_has_simple_call_op
auto a11
= views::split(' ');
59 // Verify composition of simple closures is simple.
60 __closure_has_simple_call_op
auto b
61 = (a00
| a01
) | (a02
| a03
) | (a04
| a05
| a06
) | (a07
| a08
| a09
| a10
) | a11
;
63 // Verify views::split(non_view_range) is an exception.
65 auto a12
= views::split(s
);
66 static_assert(!__closure_has_simple_call_op
<decltype(a12
)>);
67 static_assert(!__closure_has_simple_call_op
<decltype(a12
| a00
)>);
68 static_assert(!__closure_has_simple_call_op
<decltype(a00
| a12
)>);
74 // Range adaptor closures with a simple operator() aren't implemented using a
75 // fallback deleted overload, so when a call is ill-formed overload resolution
79 views::transform(badarg
)(x
); // { dg-error "no match" }
80 views::filter(badarg
)(x
); // { dg-error "no match" }
81 views::take_while(badarg
)(x
); // { dg-error "no match" }
82 views::drop_while(badarg
)(x
); // { dg-error "no match" }
84 (views::transform(badarg
) | views::all
)(x
); // { dg-error "no match" }
85 (views::filter(badarg
) | views::all
)(x
); // { dg-error "no match" }
86 (views::take_while(badarg
) | views::all
)(x
); // { dg-error "no match" }
87 (views::drop_while(badarg
) | views::all
)(x
); // { dg-error "no match" }
89 // In practice, range adaptor closures with non-simple operator() are
90 // implemented using a fallback deleted overload, so when a call is
91 // ill-formed overload resolution succeeds but selects the deleted overload
92 // (but only when the closure is invoked as an rvalue).
93 views::split(badarg
)(x
); // { dg-error "deleted function" }
94 (views::split(badarg
) | views::all
)(x
); // { dg-error "deleted function" }
95 auto a0
= views::split(badarg
);
96 a0(x
); // { dg-error "no match" };
97 auto a1
= a0
| views::all
;
98 a1(x
); // { dg-error "no match" }
100 views::take(badarg
)(x
); // { dg-error "deleted" }
101 views::drop(badarg
)(x
); // { dg-error "deleted" }
102 (views::take(badarg
) | views::all
)(x
); // { dg-error "deleted" }
103 (views::drop(badarg
) | views::all
)(x
); // { dg-error "deleted" }
109 // PR libstdc++/100940
111 struct S
{ operator int() && { return 5; }; };
112 x
| std::views::take(S
{});
113 x
| std::views::drop(S
{});
116 // { dg-prune-output "in requirements" }