// { dg-do run { target c++20 } } // { dg-skip-if "requires hosted libstdc++ for cassert" { ! hostedlib } } #include template concept C = __is_class(T); template concept D = __is_empty(T); struct X { } x; struct Y { int n; } y; int called = 0; // Test constrained member definitions template struct S1 { void f1() requires C { } void f2() requires C { called = 1; } void f2() requires (not C) { called = 2; } void f3() { called = 1; } void f3() requires C { called = 2; } void f3() requires C and D { called = 3; } void g1() requires C and true; void g2() requires C; void g2() requires (not C); void g3(); void g3() requires C; void g3() requires C and D; template void h1(U u) { called = 1; } template void h2(U u); template void h3(U u) requires D; }; template struct S2 { void f(T) requires D; }; int main() { S1 sx; S1 sy; S1 si; // Defined in-class sx.f1(); sx.f2(); assert(called == 1); sx.f3(); assert(called == 3); sy.f1(); sy.f2(); assert(called == 1); sy.f3(); assert(called == 2); si.f2(); assert(called == 2); si.f3(); assert(called == 1); // Member function template tests S1 s1i; s1i.h1(x); assert(called == 1); s1i.h2(x); assert(called == 2); s1i.h3(x); assert(called == 3); // Defined out of class. sx.g1(); sx.g2(); assert(called == 1); sx.g3(); assert(called == 3); sy.g1(); sy.g2(); assert(called == 1); sy.g3(); assert(called == 2); si.g2(); assert(called == 2); si.g3(); assert(called == 1); } template void S1::g1() requires C and true { } template void S1::g2() requires C { called = 1; } template void S1::g2() requires (not C) { called = 2; } template void S1::g3() { called = 1; } template void S1::g3() requires C { called = 2; } template void S1::g3() requires C and D { called = 3; } template template void S1::h2(U u) { called = 2; } template template void S1::h3(U u) requires D { called = 3; } template void S2::f(T t) requires D { called = 4; }