[RISCV][FMV] Support target_clones (#85786)
[llvm-project.git] / clang / test / SemaTemplate / concepts-lambda.cpp
blob9c5807bbabdcbfc15c22bff3b668c61b10a906e3
1 // RUN: %clang_cc1 -std=c++20 -verify %s
2 // RUN: %clang_cc1 -std=c++20 -verify %s -triple powerpc64-ibm-aix
4 namespace GH57945 {
5 template<typename T>
6 concept c = true;
8 template<typename>
9 auto f = []() requires c<void> {
12 void g() {
13 f<int>();
17 namespace GH57945_2 {
18 template<typename>
19 concept c = true;
21 template<typename T>
22 auto f = [](auto... args) requires c<T> {
25 template <typename T>
26 auto f2 = [](auto... args)
27 requires (sizeof...(args) > 0)
28 {};
30 void g() {
31 f<void>();
32 f2<void>(5.0);
36 namespace GH57958 {
37 template<class> concept C = true;
38 template<int> constexpr bool v = [](C auto) { return true; }(0);
39 int _ = v<0>;
41 namespace GH57958_2 {
42 template<class> concept C = true;
43 template<int> constexpr bool v = [](C auto...) { return true; }(0);
44 int _ = v<0>;
47 namespace GH57971 {
48 template<typename>
49 concept any = true;
51 template<typename>
52 auto f = [](any auto) {
55 using function_ptr = void(*)(int);
56 function_ptr ptr = f<void>;
59 // GH58368: A lambda defined in a concept requires we store
60 // the concept as a part of the lambda context.
61 namespace LambdaInConcept {
62 using size_t = unsigned long;
64 template<size_t...Ts>
65 struct IdxSeq{};
67 template <class T, class... Ts>
68 concept NotLike = true;
70 template <size_t, class... Ts>
71 struct AnyExcept {
72 template <NotLike<Ts...> T> operator T&() const;
73 template <NotLike<Ts...> T> operator T&&() const;
76 template <class T>
77 concept ConstructibleWithN = (requires {
78 []<size_t I, size_t... Idxs>
79 (IdxSeq<I, Idxs...>)
80 requires requires { T{AnyExcept<I, T>{}}; }
81 { }
82 (IdxSeq<1,2,3>{});
83 });
85 struct Foo {
86 int i;
87 double j;
88 char k;
91 static_assert(ConstructibleWithN<Foo>);
93 namespace GH56556 {
95 template <typename It>
96 inline constexpr It declare ();
98 template <typename It, template <typename> typename Template>
99 concept D = requires {
100 { [] <typename T1> (Template<T1> &) {}(declare<It &>()) };
103 template <typename T>
104 struct B {};
106 template <typename T>
107 struct Adapter;
109 template <D<B> T>
110 struct Adapter<T> {};
112 template struct Adapter<B<int>>;
114 } // namespace GH56556
116 namespace GH82849 {
118 template <class T>
119 concept C = requires(T t) {
120 requires requires (T u) {
121 []<class V>(V) {
122 return requires(V v) {
123 [](V w) {}(v);
125 }(t);
129 template <class From>
130 struct Widget;
132 template <C F>
133 struct Widget<F> {
134 static F create(F from) {
135 return from;
139 template <class>
140 bool foo() {
141 return C<int>;
144 void bar() {
145 // https://github.com/llvm/llvm-project/issues/49570#issuecomment-1664966972
146 Widget<char>::create(0);
149 } // namespace GH82849
153 // GH60642 reported an assert being hit, make sure we don't assert.
154 namespace GH60642 {
155 template<auto Q> concept C = requires { Q.template operator()<float>(); };
156 template<class> concept D = true;
157 static_assert(C<[]<D>{}>); // ok
158 template<class> concept E = C<[]<D>{}>;
159 static_assert(E<int>); // previously Asserted.
161 // ensure we properly diagnose when "D" is false.
162 namespace DIsFalse {
163 template<auto Q> concept C = requires { Q.template operator()<float>(); };
164 template<class> concept D = false;
165 static_assert(C<[]<D>{}>);
166 // expected-error@-1{{static assertion failed}}
167 // expected-note@-2{{does not satisfy 'C'}}
168 // expected-note@-5{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}}
169 template<class> concept E = C<[]<D>{}>;
170 static_assert(E<int>);
171 // expected-error@-1{{static assertion failed}}
172 // expected-note@-2{{because 'int' does not satisfy 'E'}}
173 // expected-note@-4{{does not satisfy 'C'}}
174 // expected-note@-11{{because 'Q.template operator()<float>()' would be invalid: no matching member function for call to 'operator()'}}
178 namespace ReturnTypeRequirementInLambda {
179 template <typename T>
180 concept C1 = true;
182 template <class T>
183 concept test = [] {
184 return requires(T t) {
185 { t } -> C1;
187 }();
189 static_assert(test<int>);
191 template <typename T>
192 concept C2 = true;
193 struct S1 {
194 int f1() { return 1; }
197 void foo() {
198 auto make_caller = []<auto member> {
199 return [](S1 *ps) {
200 if constexpr (requires {
201 { (ps->*member)() } -> C2;
207 auto caller = make_caller.operator()<&S1::f1>();
209 } // namespace ReturnTypeRequirementInLambda
211 namespace GH73418 {
212 void foo() {
213 int x;
214 [&x](auto) {
215 return [](auto y) {
216 return [](auto obj, auto... params)
217 requires requires {
218 sizeof...(params);
219 [](auto... pack) {
220 return sizeof...(pack);
221 }(params...);
223 { return false; }(y);
224 }(x);
225 }(x);
227 } // namespace GH73418
229 namespace GH93821 {
231 template <class>
232 concept C = true;
234 template <class...>
235 concept D = []<C T = int>() { return true; }();
237 D auto x = 0;
239 } // namespace GH93821
241 namespace dependent_param_concept {
242 template <typename... Ts> void sink(Ts...) {}
243 void dependent_param() {
244 auto L = [](auto... x) {
245 return [](decltype(x)... y) {
246 return [](int z)
247 requires requires { sink(y..., z); }
251 L(0, 1)(1, 2)(1);
253 } // namespace dependent_param_concept
255 namespace init_captures {
256 template <int N> struct V {};
258 void sink(V<0>, V<1>, V<2>, V<3>, V<4>) {}
260 void init_capture_pack() {
261 auto L = [](auto... z) {
262 return [=](auto... y) {
263 return [... w = z, y...](auto)
264 requires requires { sink(w..., y...); }
268 L(V<0>{}, V<1>{}, V<2>{})(V<3>{}, V<4>{})(1);
271 void dependent_capture_packs() {
272 auto L = [](auto... z) {
273 return [... w = z](auto... y) {
274 return [... c = w](auto)
275 requires requires { sink(c..., y...); }
279 L(V<0>{}, V<1>{}, V<2>{})(V<3>{}, V<4>{})(1);
281 } // namespace init_captures