1 // { dg-do run }
2 // { dg-options "-std=c++17 -fconcepts" }
3 
4 #include <cassert>
5 
6 template<typename T>
C()7   concept bool C() { return __is_class(T); }
8 
9 template<typename T>
D()10   concept bool D() { return C<T>() && __is_empty(T); }
11 
12 struct X { } x;
13 struct Y { int n; } y;
14 
15 int called = 0;
16 
17 template<typename T>
18   struct S {
fS19     void f() { called = 0; }                 // #1
fS20     void f() requires C<T>() { called = 0; } // #2
21 
gS22     void g() requires C<T>() { } // #1
gS23     void g() requires D<T>() { } // #2
24   };
25 
f()26 template<> void S<int>::f() { called = 1; } // Spec of #1
f()27 template<> void S<X>::f() { called = 2; } // Spec of #2
28 
g()29 template<> void S<X>::g() { called = 3; } // Spec of #2
g()30 template<> void S<Y>::g() { called = 4; } // Spec of #1
31 
main()32 int main() {
33   S<double> sd;
34   S<int> si;
35   S<X> sx;
36   S<Y> sy;
37 
38   sd.f();
39   assert(called == 0);
40   si.f();
41   assert(called == 1);
42   sx.f();
43   assert(called == 2);
44   sy.f();
45   assert(called == 0);
46 
47   sx.g();
48   assert(called == 3);
49   sy.g();
50   assert(called == 4);
51 }
52