c++: P0847R7 (deducing this) - xobj lambdas. [PR102609]
[official-gcc.git] / gcc / testsuite / g++.dg / cpp2a / concepts-ts3.C
blob6f7ed1ffee4671342a6b393537026e92b528e511
1 // { dg-do compile { target c++20 } }
2 // { dg-additional-options "-fconcepts-ts" }
4 // Basic tests using variable concepts.
6 template<typename T>
7 concept bool Type = true;
9 template<typename T>
10 concept bool False = false;
12 template<typename T>
13 concept bool Class = __is_class(T);
15 template<typename T>
16 concept bool EmptyClass = Class<T> && __is_empty(T);
18 template<typename T, typename U>
19 concept bool Classes = __is_class(T) && __is_class (U);
21 struct empty { };
23 struct nonempty { int n; };
25 static_assert(Type<int>);
26 static_assert(False<int>); // { dg-error "static assertion failed" }
28 // Basic checks
30 template<typename T>
31   requires Type<T>
32 int fn1(T t) { return 0; }
34 template<typename T>
35   requires False<T>
36 int fn2(T t) { return 0; }
38 void driver()
40   fn1(0); // OK
41   fn2(0); // { dg-error "" }
44 // Ordering
46 template<typename T>
47 concept bool Cf = requires (T t) { t.f(); };
49 template<typename T>
50 concept bool Cfg = Cf<T> && requires (T t) { t.g(); };
52 template<typename T>
53 concept bool Cf2 = requires (T t) { t.f(); };
55 template<typename T>
56 constexpr int algo(T t) { return 0; }
58 template<typename T> requires Cf<T>
59 constexpr int algo(T t) { return 1; }
61 template<typename T> requires Cfg<T>
62 constexpr int algo(T t) { return 2; }
64 template<typename T> requires Cf<T>
65 constexpr int ambig(T t) { return 1; }
67 template<typename T> requires Cf2<T>
68 constexpr int ambig(T t) { return 1; }
70 struct T1 {
71   void f() { }
74 struct T2 : T1 {
75   void g() { }
78 void driver_0()
80   T1 x;
81   T2 y;
82   static_assert(algo(0) == 0);
83   static_assert(algo(x) == 1);
84   static_assert(algo(y) == 2);
85   ambig(x); // { dg-error "call of overload | is ambiguous" }
88 template<typename T>
89 struct S
91   void f() requires Class<T> { }
92   
93   template<typename U>
94   struct Inner
95   {
96     void g() requires Classes<T, U> { }
97   };
99   template<typename U> requires Classes<T, U> void h(U) { }
102 struct X { };
104 void driver_1()
106   S<X> s1;
107   s1.f(); // OK
108   s1.h(s1); // OK
109   s1.h(0); // { dg-error "no matching function" }
111   S<int> s2;
112   s2.f(); // { dg-error "no matching function" }
114   S<X>::Inner<X> si1;
115   si1.g();
116   
117   S<X>::Inner<int> si2;
118   si2.g(); // { dg-error "no matching function" }
121 // Check constraints on non-dependent arguments, even when in a
122 // dependent context.
124 template<typename T> requires Class<T> void f1(T x) { }
126 // fn1-2.C -- Dependent checks
127 template<typename T>
128 void caller_1(T x) 
130   f1(x); // Unchecked dependent arg.
131   f1(empty{}); // Checked non-dependent arg, but OK
132   f1(0); // { dg-error "" }
135 // fn3.c -- Ordering
136 template<typename T> 
137   requires Class<T> 
138 constexpr int f2(T x) { return 1; }
140 template<typename T> 
141   requires EmptyClass<T>
142 constexpr int f2(T x) { return 2; }
144 template<typename T> 
145 constexpr int f3(T x) requires Class<T> { return 1; }
147 template<typename T> 
148 constexpr int f3(T x) requires EmptyClass<T> { return 2; }
150 void driver_2() 
152   f2(0); // { dg-error "no matching function" }
153   static_assert (f2(empty{}) == 2);
154   static_assert (f2(nonempty{}) == 1);
155   f3(0); // { dg-error "no matching function" }
156   static_assert (f3(empty{}) == 2);
157   static_assert (f3(nonempty{}) == 1);
160 // fn8.C -- Address of overloaded functions
161 template<typename T> requires Type<T> void ok(T) { }
162 template<typename T> requires Class<T> void err(T) { }
164 auto p1 = &ok<int>;
165 auto p2 = &err<int>; // { dg-error "" }
166 void (*p3)(int) = &ok<int>;
167 void (*p4)(int) = &err<int>; // { dg-error "no matches" }
168 void (*p5)(int) = &ok;
169 void (*p6)(int) = &err; // { dg-error "no matches" }
171 template<typename T> void g(T x) { }
173 void driver_3 () 
175   g(&ok<int>);
176   g(&err<int>); // { dg-error "no match" }
180 struct S2 {
181   template<typename T> requires Type<T> int ok(T) { return 0; }
182   template<typename T> requires Class<T> int err(T) { return 0; }
185 auto p7 = &S2::ok<int>;
186 auto p8 = &S2::err<int>; // { dg-error "" }
187 int (S2::*p9)(int) = &S2::ok<int>;
188 int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
189 int (S2::*p11)(int) = &S2::ok;
190 int (S2::*p12)(int) = &S2::err; // { dg-error "no matches" }
192 // fn9.C -- Ordering with function address
193 template<typename T> 
194   requires Class<T>
195 constexpr int fn(T) { return 1; }
197 template<typename T> 
198   requires EmptyClass<T>
199 constexpr int fn(T) { return 2; }
201 struct S3 
203   template<typename T> 
204     requires Class<T>
205   constexpr int fn(T) const { return 1; }
206   
207   template<typename T> 
208     requires EmptyClass<T>
209   constexpr int fn(T) const { return 2; }
212 void driver_5 () {
213   struct X { };
214   struct Y { X x; };
216   constexpr X x;
217   constexpr Y y;
218   constexpr S3 s;
220   constexpr auto p1 = &fn<X>; // Empty f
221   static_assert (p1(x) == 2);
223   constexpr auto p2 = &fn<Y>; // Class f
224   static_assert(p2(y) == 1);
226   constexpr auto p3 = &S3::fn<X>; // Empty f
227   static_assert((s.*p3)(x) == 2);
229   constexpr auto p4 = &S3::fn<Y>; // Empty f
230   static_assert((s.*p4)(y) == 1);
234 // Redeclarations
236 // FIXME: This should be a diagnosable error. The programmer has moved
237 // the requirements from the template-head to the declarator.
238 template<typename T> requires Type<T> void f3();
239 template<typename T> void f3() requires Type<T>;
241 void driver_4()
243   f3<int>(); // { dg-error "call of overload | ambiguous" }
246 template<template<typename T> requires true class X> void f4();
247 template<template<typename T> class X> void f4(); // OK: different declarations
249 template<typename T> requires Type<T> void def() { }
250 template<typename T> requires Type<T> void def() { } // { dg-error "redefinition" }