comparison gcc/testsuite/g++.dg/cpp2a/concepts-fn1.C @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 // { dg-do compile { target c++2a } }
2
3 template<typename T>
4 concept Type = true;
5
6 template<typename T>
7 concept False = false;
8
9 template<typename T>
10 concept Class = __is_class(T);
11
12 template<typename T>
13 concept EmptyClass = Class<T> && __is_empty(T);
14
15 template<typename T, typename U>
16 concept Classes = __is_class(T) && __is_class (U);
17
18 struct empty { };
19
20 struct nonempty { int n; };
21
22 static_assert(Type<int>);
23 static_assert(False<int>); // { dg-error "static assertion failed" }
24
25 // Basic checks
26
27 template<typename T>
28 requires Type<T>
29 int fn1(T t) { return 0; }
30
31 template<typename T>
32 requires False<T>
33 int fn2(T t) { return 0; }
34
35 void driver()
36 {
37 fn1(0); // OK
38 fn2(0); // { dg-error "" }
39 }
40
41 // Ordering
42
43 template<typename T>
44 concept Cf = requires (T t) { t.f(); };
45
46 template<typename T>
47 concept Cfg = Cf<T> && requires (T t) { t.g(); };
48
49 template<typename T>
50 concept Cf2 = requires (T t) { t.f(); };
51
52 template<typename T>
53 constexpr int algo(T t) { return 0; }
54
55 template<typename T> requires Cf<T>
56 constexpr int algo(T t) { return 1; }
57
58 template<typename T> requires Cfg<T>
59 constexpr int algo(T t) { return 2; }
60
61 template<typename T> requires Cf<T>
62 constexpr int ambig(T t) { return 1; }
63
64 template<typename T> requires Cf2<T>
65 constexpr int ambig(T t) { return 1; }
66
67 struct T1 {
68 void f() { }
69 };
70
71 struct T2 : T1 {
72 void g() { }
73 };
74
75 void driver_0()
76 {
77 T1 x;
78 T2 y;
79 static_assert(algo(0) == 0);
80 static_assert(algo(x) == 1);
81 static_assert(algo(y) == 2);
82 ambig(x); // { dg-error "call of overload | is ambiguous" }
83 }
84
85 template<typename T>
86 struct S
87 {
88 void f() requires Class<T> { }
89
90 template<typename U>
91 struct Inner
92 {
93 void g() requires Classes<T, U> { }
94 };
95
96 template<typename U> requires Classes<T, U> void h(U) { }
97 };
98
99 struct X { };
100
101 void driver_1()
102 {
103 S<X> s1;
104 s1.f(); // OK
105 s1.h(s1); // OK
106 s1.h(0); // { dg-error "no matching function" }
107
108 S<int> s2;
109 s2.f(); // { dg-error "no matching function" }
110
111 S<X>::Inner<X> si1;
112 si1.g();
113
114 S<X>::Inner<int> si2;
115 si2.g(); // { dg-error "no matching function" }
116 }
117
118 // Check constraints on non-dependent arguments, even when in a
119 // dependent context.
120
121 template<typename T> requires Class<T> void f1(T x) { }
122
123 // fn1-2.C -- Dependent checks
124 template<typename T>
125 void caller_1(T x)
126 {
127 f1(x); // Unchecked dependent arg.
128 f1(empty{}); // Checked non-dependent arg, but OK
129 f1(0); // { dg-error "" }
130 }
131
132 // fn3.c -- Ordering
133 template<typename T>
134 requires Class<T>
135 constexpr int f2(T x) { return 1; }
136
137 template<typename T>
138 requires EmptyClass<T>
139 constexpr int f2(T x) { return 2; }
140
141 template<typename T>
142 constexpr int f3(T x) requires Class<T> { return 1; }
143
144 template<typename T>
145 constexpr int f3(T x) requires EmptyClass<T> { return 2; }
146
147 void driver_2()
148 {
149 f2(0); // { dg-error "no matching function" }
150 static_assert (f2(empty{}) == 2);
151 static_assert (f2(nonempty{}) == 1);
152 f3(0); // { dg-error "no matching function" }
153 static_assert (f3(empty{}) == 2);
154 static_assert (f3(nonempty{}) == 1);
155 }
156
157 // fn8.C -- Address of overloaded functions
158 template<typename T> requires Type<T> void ok(T) { }
159 template<typename T> requires Class<T> void err(T) { }
160
161 auto p1 = &ok<int>;
162 auto p2 = &err<int>; // { dg-error "" }
163 void (*p3)(int) = &ok<int>;
164 void (*p4)(int) = &err<int>; // { dg-error "no matches" }
165 void (*p5)(int) = &ok;
166 void (*p6)(int) = &err; // { dg-error "no matches" }
167
168 template<typename T> void g(T x) { }
169
170 void driver_3 ()
171 {
172 g(&ok<int>);
173 g(&err<int>); // { dg-error "no matches" }
174 }
175
176
177 struct S2 {
178 template<typename T> requires Type<T> int ok(T) { return 0; }
179 template<typename T> requires Class<T> int err(T) { return 0; }
180 };
181
182 auto p7 = &S2::ok<int>;
183 auto p8 = &S2::err<int>; // { dg-error "" }
184 int (S2::*p9)(int) = &S2::ok<int>;
185 int (S2::*p10)(int) = &S2::err<int>; // { dg-error "no matches" }
186 int (S2::*p11)(int) = &S2::ok;
187 int (S2::*p12)(int) = &S2::err; // { dg-error "no matches" }
188
189 // fn9.C -- Ordering with function address
190 template<typename T>
191 requires Class<T>
192 constexpr int fn(T) { return 1; }
193
194 template<typename T>
195 requires EmptyClass<T>
196 constexpr int fn(T) { return 2; }
197
198 struct S3
199 {
200 template<typename T>
201 requires Class<T>
202 constexpr int fn(T) const { return 1; }
203
204 template<typename T>
205 requires EmptyClass<T>
206 constexpr int fn(T) const { return 2; }
207 };
208
209 void driver_5 () {
210 struct X { };
211 struct Y { X x; };
212
213 constexpr X x;
214 constexpr Y y;
215 constexpr S3 s;
216
217 constexpr auto p1 = &fn<X>; // Empty f
218 static_assert (p1(x) == 2);
219
220 constexpr auto p2 = &fn<Y>; // Class f
221 static_assert(p2(y) == 1);
222
223 constexpr auto p3 = &S3::fn<X>; // Empty f
224 static_assert((s.*p3)(x) == 2);
225
226 constexpr auto p4 = &S3::fn<Y>; // Empty f
227 static_assert((s.*p4)(y) == 1);
228 }
229
230
231 // Redeclarations
232
233 // FIXME: This should be a diagnosable error. The programmer has moved
234 // the requirements from the template-head to the declarator.
235 template<typename T> requires Type<T> void f3();
236 template<typename T> void f3() requires Type<T>;
237
238 void driver_4()
239 {
240 f3<int>(); // { dg-error "call of overload | ambiguous" }
241 }
242
243 template<template<typename T> requires true class X> void f4();
244 template<template<typename T> class X> void f4(); // OK: different declarations
245
246 template<typename T> requires Type<T> void def() { }
247 template<typename T> requires Type<T> void def() { } // { dg-error "redefinition" }
248