1 // { dg-do compile { target c++17 } }
2 // { dg-options "-fconcepts" }
5 concept C = requires (T t) { t.mf(); };
8 concept CA1 = C<typename T::ca1_type>;
11 concept CA2 = CA1<T> && requires () { typename T::ca2_type; };
14 concept CA3 = CA2<T> && requires () { typename T::ca3_type; };
17 concept CB1 = requires () { typename T::cb1_type; };
20 concept CB2 = CB1<T> && requires () { typename T::cb2_type; };
23 concept CB3 = CB2<T> && requires () { typename T::cb3_type; };
26 struct MC { void mf(); };
27 static_assert(C<MC>, "");
30 struct MA1 { using ca1_type = MC; };
31 struct MA2 : MA1 { using ca2_type = int; };
32 struct MA3 : MA2 { using ca3_type = int; };
33 static_assert(CA1<MA1>, "");
34 static_assert(CA2<MA2>, "");
35 static_assert(CA3<MA3>, "");
37 struct MB1 { using cb1_type = int; };
38 struct MB2 : MB1 { using cb2_type = int; };
39 struct MB3 : MB2 { using cb3_type = int; };
40 static_assert(CB1<MB1>, "");
41 static_assert(CB2<MB2>, "");
42 static_assert(CB3<MB3>, "");
45 template<typename T1, typename T2>
48 template<CA1 T1, CB1 T2>
49 struct S<T1, T2> // Specialization #1
51 static constexpr int value = 1;
54 template<CA1 T1, CB2 T2>
56 struct S<T1, T2> // Specialization #2
58 static constexpr int value = 2;
61 template<CA2 T1, CB3 T2>
63 struct S<T1, T2> // Specialization #3
65 static constexpr int value = 3;
68 static_assert(S<MA1,MB1>::value == 1, "");
69 static_assert(S<MA1,MB2>::value == 2, "");
70 static_assert(S<MA1,MB3>::value == 2, "");
71 static_assert(S<MA2,MB1>::value == 1, "");
72 static_assert(S<MA2,MB2>::value == 1, "");
73 static_assert(S<MA2,MB3>::value == 3, "");
74 static_assert(S<MA3,MB1>::value == 1, "");
75 static_assert(S<MA3,MB2>::value == 1, "");
76 static_assert(S<MA3,MB3>::value == 1, "");