]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/std/ranges/adaptors/100577.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / std / ranges / adaptors / 100577.cc
1 // Copyright (C) 2021-2023 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 #include <functional>
25 #if __STDC_HOSTED__
26 #include <string>
27 #endif
28
29 namespace ranges = std::ranges;
30 namespace views = std::ranges::views;
31
32 void
33 test01()
34 {
35 // Verify adaptors are deemed to have simple extra arguments when appropriate.
36 using views::__adaptor::__adaptor_has_simple_extra_args;
37 using std::identity;
38 static_assert(__adaptor_has_simple_extra_args<decltype(views::transform), identity>);
39 static_assert(__adaptor_has_simple_extra_args<decltype(views::filter), identity>);
40 static_assert(__adaptor_has_simple_extra_args<decltype(views::drop), int>);
41 static_assert(__adaptor_has_simple_extra_args<decltype(views::take), int>);
42 static_assert(__adaptor_has_simple_extra_args<decltype(views::take_while), identity>);
43 static_assert(__adaptor_has_simple_extra_args<decltype(views::drop_while), identity>);
44 static_assert(__adaptor_has_simple_extra_args<decltype(views::lazy_split), char>);
45 #if __STDC_HOSTED__
46 static_assert(__adaptor_has_simple_extra_args<decltype(views::lazy_split), std::string_view>);
47 static_assert(!__adaptor_has_simple_extra_args<decltype(views::lazy_split), std::string>);
48 #endif
49
50 using views::__adaptor::__closure_has_simple_call_op;
51 __closure_has_simple_call_op auto a00 = views::all;
52 __closure_has_simple_call_op auto a01 = views::transform(std::identity{});
53 __closure_has_simple_call_op auto a02 = views::filter(std::identity{});
54 __closure_has_simple_call_op auto a03 = views::drop(42);
55 __closure_has_simple_call_op auto a04 = views::take(42);
56 __closure_has_simple_call_op auto a05 = views::take_while(std::identity{});
57 __closure_has_simple_call_op auto a06 = views::drop_while(std::identity{});
58 __closure_has_simple_call_op auto a07 = views::join;
59 __closure_has_simple_call_op auto a08 = views::common;
60 __closure_has_simple_call_op auto a09 = views::reverse;
61 __closure_has_simple_call_op auto a10 = views::keys;
62 __closure_has_simple_call_op auto a11 = views::lazy_split(' ');
63 __closure_has_simple_call_op auto a11a = views::split(' ');
64 // Verify composition of simple closures is simple.
65 __closure_has_simple_call_op auto b
66 = (a00 | a01) | (a02 | a03) | (a04 | a05 | a06) | (a07 | a08 | a09 | a10) | a11;
67
68 #if __STDC_HOSTED__
69 // Verify views::lazy_split(non_view_range) is an exception.
70 extern std::string s;
71 auto a12 = views::lazy_split(s);
72 static_assert(!__closure_has_simple_call_op<decltype(a12)>);
73 static_assert(!__closure_has_simple_call_op<decltype(a12 | a00)>);
74 static_assert(!__closure_has_simple_call_op<decltype(a00 | a12)>);
75
76 // Likewise views::split(non_view_range).
77 auto a12a = views::split(s);
78 static_assert(!__closure_has_simple_call_op<decltype(a12a)>);
79 static_assert(!__closure_has_simple_call_op<decltype(a12a | a00)>);
80 static_assert(!__closure_has_simple_call_op<decltype(a00 | a12a)>);
81 #endif
82 }
83
84 void
85 test02()
86 {
87 // Range adaptor closures with a simple operator() aren't implemented using a
88 // fallback deleted overload, so when a call is ill-formed overload resolution
89 // fails.
90 extern int x[10];
91 struct { } badarg;
92 views::transform(badarg)(x); // { dg-error "no match" }
93 views::filter(badarg)(x); // { dg-error "no match" }
94 views::take_while(badarg)(x); // { dg-error "no match" }
95 views::drop_while(badarg)(x); // { dg-error "no match" }
96
97 (views::transform(badarg) | views::all)(x); // { dg-error "no match" }
98 (views::filter(badarg) | views::all)(x); // { dg-error "no match" }
99 (views::take_while(badarg) | views::all)(x); // { dg-error "no match" }
100 (views::drop_while(badarg) | views::all)(x); // { dg-error "no match" }
101
102 // In practice, range adaptor closures with non-simple operator() are
103 // implemented using a fallback deleted overload, so when a call is
104 // ill-formed overload resolution succeeds but selects the deleted overload
105 // (but only when the closure is invoked as an rvalue).
106 views::lazy_split(badarg)(x); // { dg-error "deleted function" }
107 (views::lazy_split(badarg) | views::all)(x); // { dg-error "deleted function" }
108 auto a0 = views::lazy_split(badarg);
109 a0(x); // { dg-error "no match" };
110 auto a1 = a0 | views::all;
111 a1(x); // { dg-error "no match" }
112
113 views::split(badarg)(x); // { dg-error "deleted function" }
114 (views::split(badarg) | views::all)(x); // { dg-error "deleted function" }
115 auto a0a = views::split(badarg);
116 a0a(x); // { dg-error "no match" };
117 auto a1a = a0a | views::all;
118 a1a(x); // { dg-error "no match" }
119
120 views::take(badarg)(x); // { dg-error "deleted" }
121 views::drop(badarg)(x); // { dg-error "deleted" }
122 (views::take(badarg) | views::all)(x); // { dg-error "deleted" }
123 (views::drop(badarg) | views::all)(x); // { dg-error "deleted" }
124 }
125
126 void
127 test03()
128 {
129 // PR libstdc++/100940
130 extern int x[10];
131 struct S { operator int() && { return 5; }; };
132 x | std::views::take(S{});
133 x | std::views::drop(S{});
134 }
135
136 void
137 test04()
138 {
139 #if __STDC_HOSTED__
140 // Non-trivially-copyable extra arguments make a closure not simple.
141 using F = std::function<bool(bool)>;
142 static_assert(!std::is_trivially_copyable_v<F>);
143 using views::__adaptor::__closure_has_simple_call_op;
144 static_assert(!__closure_has_simple_call_op<decltype(views::take_while(std::declval<F>()))>);
145 static_assert(!__closure_has_simple_call_op<decltype(views::drop_while(std::declval<F>()))>);
146 static_assert(!__closure_has_simple_call_op<decltype(views::filter(std::declval<F>()))>);
147 static_assert(!__closure_has_simple_call_op<decltype(views::transform(std::declval<F>()))>);
148 #endif
149 }
150
151 // { dg-prune-output "in requirements" }