]> gcc.gnu.org Git - gcc.git/blob - libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc
libstdc++: Refine range adaptors' "simple extra args" mechanism [PR100940]
[gcc.git] / libstdc++-v3 / testsuite / std / ranges / adaptors / 100577.cc
1 // Copyright (C) 2021 Free Software Foundation, Inc.
2 //
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)
7 // any later version.
8
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.
13
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/>.
17
18 // { dg-options "-std=gnu++2a" }
19 // { dg-do compile { target c++2a } }
20
21 // PR libstdc++/100577
22
23 #include <ranges>
24
25 namespace ranges = std::ranges;
26 namespace views = std::ranges::views;
27
28 void
29 test01()
30 {
31 // Verify adaptors are deemed to have simple extra arguments when appropriate.
32 using views::__adaptor::__adaptor_has_simple_extra_args;
33 using std::identity;
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>);
43
44 // Verify all adaptor closures except for views::split(pattern) have a simple
45 // operator().
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;
62
63 // Verify views::split(non_view_range) is an exception.
64 extern std::string s;
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)>);
69 }
70
71 void
72 test02()
73 {
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
76 // fails.
77 extern int x[10];
78 struct { } badarg;
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" }
83
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" }
88
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" }
99
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" }
104 }
105
106 void
107 test03()
108 {
109 // PR libstdc++/100940
110 extern int x[10];
111 struct S { operator int() && { return 5; }; };
112 x | std::views::take(S{});
113 x | std::views::drop(S{});
114 }
115
116 // { dg-prune-output "in requirements" }
This page took 0.04422 seconds and 5 git commands to generate.