[RISCV] Simplify usage of SplatPat_simm5_plus1. NFC (#125340)
[llvm-project.git] / clang / test / SemaTemplate / concepts-out-of-line-def.cpp
blob5af4ec75cae90ff897864ad35c5fe29441554741
1 // RUN: %clang_cc1 -std=c++20 -verify %s
3 static constexpr int PRIMARY = 0;
4 static constexpr int SPECIALIZATION_CONCEPT = 1;
5 static constexpr int SPECIALIZATION_REQUIRES = 2;
7 template <class T>
8 concept Concept = (sizeof(T) >= 2 * sizeof(int));
10 struct XY {
11 int x;
12 int y;
15 namespace members {
17 template <class T, class U> struct S {
18 static constexpr int primary();
21 template <class T, class U> constexpr int S<T, U>::primary() {
22 return PRIMARY;
25 template <Concept C, class U> struct S<C, U> {
26 static constexpr int specialization();
29 template <class T, class U>
30 requires(sizeof(T) == sizeof(int))
31 struct S<T, U> {
32 static constexpr int specialization();
35 template <Concept C, class U> constexpr int S<C, U>::specialization() {
36 return SPECIALIZATION_CONCEPT;
39 template <class T, class U>
40 requires(sizeof(T) == sizeof(int))
41 constexpr int S<T, U>::specialization() {
42 return SPECIALIZATION_REQUIRES;
45 static_assert(S<char, double>::primary() == PRIMARY);
46 static_assert(S<XY, double>::specialization() == SPECIALIZATION_CONCEPT);
47 static_assert(S<int, double>::specialization() == SPECIALIZATION_REQUIRES);
49 } // namespace members
51 namespace enumerations {
53 template <class T, class U> struct S {
54 enum class E : int;
57 template <class T, class U> enum class S<T, U>::E { Value = PRIMARY };
59 template <Concept C, class U> struct S<C, U> {
60 enum class E : int;
63 template <Concept C, class U>
64 enum class S<C, U>::E {
65 Value = SPECIALIZATION_CONCEPT
68 template <class T, class U>
69 requires(sizeof(T) == sizeof(int))
70 struct S<T, U> {
71 enum class E : int;
74 template <class T, class U>
75 requires(sizeof(T) == sizeof(int))
76 enum class S<T, U>::E {
77 Value = SPECIALIZATION_REQUIRES
80 static_assert(static_cast<int>(S<char, double>::E::Value) == PRIMARY);
81 static_assert(static_cast<int>(S<XY, double>::E::Value) ==
82 SPECIALIZATION_CONCEPT);
83 static_assert(static_cast<int>(S<int, double>::E::Value) ==
84 SPECIALIZATION_REQUIRES);
86 } // namespace enumerations
88 namespace multiple_template_parameter_lists {
90 template <class Outer>
91 struct S {
92 template <class Inner>
93 static constexpr int primary(Inner);
96 template <class Outer>
97 template <class Inner>
98 constexpr int S<Outer>::primary(Inner) {
99 return PRIMARY;
102 template <Concept Outer>
103 struct S<Outer> {
104 template <class Inner>
105 static constexpr int specialization(Inner);
108 template <Concept Outer>
109 template <class Inner>
110 constexpr int S<Outer>::specialization(Inner) { return SPECIALIZATION_CONCEPT; }
112 template <class Outer>
113 requires(sizeof(Outer) == sizeof(int))
114 struct S<Outer> {
115 template <class Inner>
116 static constexpr int specialization(Inner);
119 template <class Outer>
120 requires(sizeof(Outer) == sizeof(int))
121 template <class Inner>
122 constexpr int S<Outer>::specialization(Inner) { return SPECIALIZATION_REQUIRES; }
124 static_assert(S<char>::primary("str") == PRIMARY);
125 static_assert(S<XY>::specialization("str") == SPECIALIZATION_CONCEPT);
126 static_assert(S<int>::specialization("str") == SPECIALIZATION_REQUIRES);
128 } // namespace multiple_template_parameter_lists
130 static constexpr int CONSTRAINED_METHOD_1 = 1;
131 static constexpr int CONSTRAINED_METHOD_2 = 2;
133 namespace constrained_members {
135 template <int>
136 struct S {
137 template <Concept C>
138 static constexpr int constrained_method();
141 template <>
142 template <Concept C>
143 constexpr int S<1>::constrained_method() { return CONSTRAINED_METHOD_1; }
145 template <>
146 template <Concept C>
147 constexpr int S<2>::constrained_method() { return CONSTRAINED_METHOD_2; }
149 static_assert(S<1>::constrained_method<XY>() == CONSTRAINED_METHOD_1);
150 static_assert(S<2>::constrained_method<XY>() == CONSTRAINED_METHOD_2);
153 template <class T1, class T2>
154 concept ConceptT1T2 = true;
156 template<typename T3>
157 struct S12 {
158 template<ConceptT1T2<T3> T4>
159 static constexpr int constrained_method();
162 template<>
163 template<ConceptT1T2<int> T5>
164 constexpr int S12<int>::constrained_method() { return CONSTRAINED_METHOD_1; }
166 template<>
167 template<ConceptT1T2<double> T5>
168 constexpr int S12<double>::constrained_method() { return CONSTRAINED_METHOD_2; }
170 static_assert(S12<int>::constrained_method<XY>() == CONSTRAINED_METHOD_1);
171 static_assert(S12<double>::constrained_method<XY>() == CONSTRAINED_METHOD_2);
173 } // namespace constrained members
175 namespace constrained_members_of_nested_types {
177 template <int>
178 struct S {
179 struct Inner0 {
180 struct Inner1 {
181 template <Concept C>
182 static constexpr int constrained_method();
187 template <>
188 template <Concept C>
189 constexpr int S<1>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }
191 template <>
192 template <Concept C>
193 constexpr int S<2>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }
195 static_assert(S<1>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_1);
196 static_assert(S<2>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_2);
199 template <class T1, class T2>
200 concept ConceptT1T2 = true;
202 template<typename T3>
203 struct S12 {
204 struct Inner0 {
205 struct Inner1 {
206 template<ConceptT1T2<T3> T4>
207 static constexpr int constrained_method();
212 template<>
213 template<ConceptT1T2<int> T5>
214 constexpr int S12<int>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_1; }
216 template<>
217 template<ConceptT1T2<double> T5>
218 constexpr int S12<double>::Inner0::Inner1::constrained_method() { return CONSTRAINED_METHOD_2; }
220 static_assert(S12<int>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_1);
221 static_assert(S12<double>::Inner0::Inner1::constrained_method<XY>() == CONSTRAINED_METHOD_2);
223 } // namespace constrained_members_of_nested_types
225 namespace constrained_member_sfinae {
227 template<int N> struct S {
228 template<class T>
229 static constexpr int constrained_method() requires (sizeof(int[N * 1073741824 + 4]) == 16) { // expected-warning {{variable length arrays in C++ are a Clang extension}} \
230 expected-note {{value 4294967296 is outside the range of representable values of type 'int'}} \
231 expected-note {{while calculating associated constraint of template 'constrained_method' here}}
232 return CONSTRAINED_METHOD_1;
235 template<class T>
236 static constexpr int constrained_method() requires (sizeof(int[N]) == 16);
239 template<>
240 template<typename T>
241 constexpr int S<4>::constrained_method() requires (sizeof(int[4]) == 16) {
242 return CONSTRAINED_METHOD_2;
245 // Verify that there is no amiguity in this case.
246 static_assert(S<4>::constrained_method<double>() == CONSTRAINED_METHOD_2);
248 } // namespace constrained_member_sfinae
250 namespace requires_expression_references_members {
252 void accept1(int x);
253 void accept2(XY xy);
255 template <class T> struct S {
256 T Field = T();
258 constexpr int constrained_method()
259 requires requires { accept1(Field); };
261 constexpr int constrained_method()
262 requires requires { accept2(Field); };
265 template <class T>
266 constexpr int S<T>::constrained_method()
267 requires requires { accept1(Field); } {
268 return CONSTRAINED_METHOD_1;
271 template <class T>
272 constexpr int S<T>::constrained_method()
273 requires requires { accept2(Field); } {
274 return CONSTRAINED_METHOD_2;
277 static_assert(S<int>().constrained_method() == CONSTRAINED_METHOD_1);
278 static_assert(S<XY>().constrained_method() == CONSTRAINED_METHOD_2);
280 } // namespace requires_expression_references_members
282 namespace GH60231 {
284 template<typename T0> concept C = true;
286 template <typename T1>
287 struct S {
288 template <typename F1> requires C<S<T1>>
289 void foo1(F1 f);
291 template <typename F2>
292 void foo2(F2 f) requires C<S<T1>>;
294 template <typename F3> requires C<F3>
295 void foo3(F3 f);
298 template <typename T2>
299 template <typename F4> requires C<S<T2>>
300 void S<T2>::foo1(F4 f) {}
302 template <typename T3>
303 template <typename F5>
304 void S<T3>::foo2(F5 f) requires C<S<T3>> {}
306 template <typename T4>
307 template <typename F6> requires C<F6>
308 void S<T4>::foo3(F6 f) {}
310 } // namespace GH60231
312 namespace GH62003 {
314 template <typename T0> concept Concept = true;
316 template <class T1>
317 struct S1 {
318 template <Concept C1>
319 static constexpr int foo();
321 template <class T2>
322 template <Concept C2>
323 constexpr int S1<T2>::foo() { return 1; }
325 template <Concept C3>
326 struct S2 {
327 template <class T3>
328 static constexpr int foo();
330 template <Concept C4>
331 template <class T4>
332 constexpr int S2<C4>::foo() { return 2; }
334 template <Concept C5>
335 struct S3 {
336 template <Concept C6>
337 static constexpr int foo();
339 template <Concept C7>
340 template <Concept C8>
341 constexpr int S3<C7>::foo() { return 3; }
343 static_assert(S1<int>::foo<int>() == 1);
344 static_assert(S2<int>::foo<int>() == 2);
345 static_assert(S3<int>::foo<int>() == 3);
347 } // namespace GH62003
349 namespace MultilevelTemplateWithPartialSpecialization {
350 template <typename>
351 concept Concept = true;
353 namespace two_level {
354 template <typename T1, int>
355 struct W0 {
356 template <typename T2>
357 requires (Concept<T2>)
358 void f(const T2 &);
361 template <typename T3>
362 struct W0<T3, 0> {
363 template <typename T4>
364 requires (Concept<T4>)
365 void f(const T4 &);
368 template <typename T3>
369 template <typename T4>
370 requires (Concept<T4>)
371 inline void W0<T3, 0>::f(const T4 &) {}
372 } // namespace two_level
374 namespace three_level {
375 template <typename T1, int>
376 struct W0 {
377 template <typename T2>
378 struct W1 {
379 template <typename T3>
380 requires (Concept<T3>)
381 void f(const T3 &);
385 template <typename T4>
386 struct W0<T4, 0> {
387 template <typename T5>
388 struct W1 {
389 template <typename T6>
390 requires (Concept<T6>)
391 void f(const T6 &);
395 template <typename T7>
396 template <typename T8>
397 template <typename T9>
398 requires (Concept<T9>)
399 inline void W0<T7, 0>::W1<T8>::f(const T9 &) {}
400 } // namespace three_level
402 } // namespace MultilevelTemplateWithPartialSpecialization
404 namespace PR62697 {
405 template<typename>
406 concept c = true;
408 template<typename T>
409 struct s {
410 void f() requires c<void(T)>;
413 template<typename T>
414 void s<T>::f() requires c<void(T)> { }
417 namespace GH62272 {
418 template<typename T> concept A = true;
419 template<typename T> struct X { A<T> auto f(); };
420 template<typename T> A<T> auto X<T>::f() {}
423 namespace GH65810 {
424 template<typename Param>
425 concept TrivialConcept =
426 requires(Param param) {
427 (void)param;
430 template <typename T>
431 struct Base {
432 class InnerClass;
435 template <typename T>
436 class Base<T>::InnerClass {
437 template <typename Param>
438 requires TrivialConcept<Param>
439 int func(Param param) const;
442 template <typename T>
443 template <typename Param>
444 requires TrivialConcept<Param>
445 int Base<T>::InnerClass::func(Param param) const {
446 return 0;
449 template<typename T>
450 struct Outermost {
451 struct Middle {
452 template<typename U>
453 struct Innermost {
454 template <typename Param>
455 requires TrivialConcept<Param>
456 int func(Param param) const;
461 template <typename T>
462 template <typename U>
463 template <typename Param>
464 requires TrivialConcept<Param>
465 int Outermost<T>::Middle::Innermost<U>::func(Param param) const {
466 return 0;
469 } // namespace GH65810
471 namespace GH61763 {
472 template<typename T, typename U>
473 concept same_as = true;
475 template <class = void>
476 struct Foo {
477 template <same_as<void> Param>
478 friend struct Bar;
481 template struct Foo<>;
483 template <same_as<void> Param>
484 struct Bar {
488 template<typename T>
489 concept ok = true;
491 struct outer {
492 template<typename T>
493 requires ok<T>
494 struct foo {};
497 template<typename U>
498 struct bar {
499 template<typename T>
500 requires ok<T>
501 friend struct outer::foo;
504 bar<int> x;
505 } // namespace GH61763
508 namespace GH74314 {
509 template <class T, class U> constexpr bool is_same_v = __is_same(T, U);
510 template <class T, class U> constexpr bool is_not_same_v = !__is_same(T, U);
512 template <class Result>
513 concept something_interesting = requires {
514 true;
515 requires is_same_v<int, Result>;
518 template <class T>
519 struct X { // #defined-here
520 void foo() requires requires { requires is_not_same_v<T, int>; };
521 void bar(decltype(requires { requires is_not_same_v<T, int>; }));
524 template <class T>
525 void X<T>::foo() requires requires { requires something_interesting<T>; } {}
526 // expected-error@-1{{definition of 'foo' does not match any declaration}}
527 // expected-note@#defined-here{{defined here}}
528 // expected-note@-8{{member declaration nearly matches}}
530 template <class T>
531 void X<T>::foo() requires requires { requires is_not_same_v<T, int>; } {} // ok
533 template <class T>
534 void X<T>::bar(decltype(requires { requires something_interesting<T>; })) {}
535 // expected-error@-1{{definition of 'bar' does not match any declaration}}
536 // expected-note@#defined-here{{defined here}}
538 template <class T>
539 void X<T>::bar(decltype(requires { requires is_not_same_v<T, int>; })) {}
540 } // namespace GH74314
542 namespace GH56482 {
543 template <typename SlotMap>
544 concept slot_map_has_reserve = true;
546 template <typename T> struct Slot_map {
547 constexpr void reserve() const noexcept
548 requires slot_map_has_reserve<Slot_map>;
550 constexpr void reserve(int) const noexcept
551 requires slot_map_has_reserve<Slot_map<T>>;
554 template <typename T>
555 constexpr void Slot_map<T>::reserve() const noexcept
556 requires slot_map_has_reserve<Slot_map<T>>
559 template <typename T>
560 constexpr void Slot_map<T>::reserve(int) const noexcept
561 requires slot_map_has_reserve<Slot_map>
563 } // namespace GH56482
565 namespace GH74447 {
566 template <typename T> struct S {
567 template <typename... U, int V>
568 void test(T target, U... value)
569 requires requires {
570 target;
571 sizeof...(value) == 1;
572 V == 2;
576 template <typename T>
577 template <typename... U, int V>
578 void S<T>::test(T target, U... value)
579 requires requires {
580 target;
581 sizeof...(value) == 1;
582 V == 2;
585 } // namespace GH74447
587 namespace GH72557 {
589 template <typename...>
590 concept IsAnyOf = true;
592 template <class... DerTs> struct DerivedCollection {
593 template <class DerT>
594 requires IsAnyOf<DerTs...>
595 unsigned long index();
598 template <class... DerTs>
599 template <class DerT>
600 requires IsAnyOf<DerTs...>
601 unsigned long DerivedCollection<DerTs...>::index() {}
603 } // namespace GH72557
605 namespace GH101735 {
607 template <class, class>
608 concept True = true;
610 template <typename T>
611 class A {
612 template <typename... Ts>
613 void method(Ts&... ts)
614 requires requires (T t) {
615 { t.method(static_cast<Ts &&>(ts)...) } -> True<void>;
619 template <typename T>
620 template <typename... Ts>
621 void A<T>::method(Ts&... ts)
622 requires requires (T t) {
623 { t.method(static_cast<Ts &&>(ts)...) } -> True<void>;
624 } {}
628 namespace GH63782 {
629 // GH63782 was also fixed by PR #80594, so let's add a test for it.
631 template<bool... Vals>
632 constexpr bool All = (Vals && ...);
634 template<bool... Bs>
635 class Class {
636 template<typename>
637 requires All<Bs...>
638 void Foo();
641 template<bool... Bs>
642 template<typename>
643 requires All<Bs...>
644 void Class<Bs...>::Foo() {
647 } // namespace GH63782
649 namespace eve {
650 // Reduced from the "eve" project
652 template <typename... Ts>
653 struct tuple {
654 template <int I0> requires(I0 <= sizeof...(Ts))
655 constexpr auto split();
658 template <typename... Ts>
659 template <int I0>
660 requires(I0 <= sizeof...(Ts))
661 constexpr auto tuple<Ts...>::split(){
662 return 0;
665 int foo() {
666 tuple<int, float> x;
667 return x.split<0>();
670 } // namespace eve
672 namespace GH93099 {
674 // Issues with sizeof...(expr)
676 template <typename T = int> struct C {
677 template <int... N>
678 requires(sizeof...(N) > 0)
679 friend class NTTP;
681 template <class... Tp>
682 requires(sizeof...(Tp) > 0)
683 friend class TP;
685 template <template <typename> class... TTp>
686 requires(sizeof...(TTp) > 0)
687 friend class TTP;
690 template <int... N>
691 requires(sizeof...(N) > 0)
692 class NTTP;
694 template <class... Tp>
695 requires(sizeof...(Tp) > 0)
696 class TP;
698 template <template <typename> class... TTp>
699 requires(sizeof...(TTp) > 0)
700 class TTP;
702 C v;
704 } // namespace GH93099
706 namespace GH115098 {
708 template <typename... Ts> struct c {
709 template <typename T>
710 requires(sizeof...(Ts) > 0)
711 friend bool operator==(c, c);
714 template <typename... Ts> struct d {
715 template <typename T>
716 requires(sizeof...(Ts) > 0)
717 friend bool operator==(d, d);
720 template struct c<int>;
721 template struct d<int, int>;
723 } // namespace GH115098
725 namespace GH123441 {
727 struct buf {
728 constexpr buf(auto&&... initList) requires (sizeof...(initList) <= 8);
731 constexpr buf::buf(auto&&... initList) requires (sizeof...(initList) <= 8) {}
733 template <class>
734 struct buffer {
735 constexpr buffer(auto&&... initList) requires (sizeof...(initList) <= 8);
738 template <class T>
739 constexpr buffer<T>::buffer(auto&&... initList) requires (sizeof...(initList) <= 8) {}
741 template <class...>
742 struct foo { // expected-note {{foo defined here}}
743 constexpr foo(auto&&... initList)
744 requires (sizeof...(initList) <= 8);
747 template <class... T>
748 constexpr foo<T...>::foo(auto&&... initList) // expected-error {{does not match any declaration}}
749 requires (sizeof...(T) <= 8) {}
751 } // namespace GH123441
753 namespace GH114685 {
755 template <typename T> struct ptr {
756 template <typename U>
757 friend ptr<U> make_item(auto &&args)
758 requires(sizeof(args) > 1);
761 template <typename U>
762 ptr<U> make_item(auto &&args)
763 requires(sizeof(args) > 1) {}
765 ptr<char> p;
767 } // namespace GH114685
769 namespace GH123472 {
771 consteval bool fn() { return true; }
773 struct S {
774 template <typename T>
775 static consteval void mfn() requires (bool(&fn));
778 template <typename T>
779 consteval void S::mfn() requires (bool(&fn)) {}