131
|
1 // { dg-do compile { target c++17 } }
|
|
2 // { dg-options "-fconcepts" }
|
111
|
3
|
|
4 template<typename T>
|
|
5 concept bool C()
|
|
6 {
|
|
7 return requires (T t) { t.mf(); };
|
|
8 }
|
|
9
|
|
10 template<typename T>
|
|
11 concept bool CA1()
|
|
12 {
|
|
13 return C<typename T::ca1_type>();
|
|
14 }
|
|
15
|
|
16 template<typename T>
|
|
17 concept bool CA2()
|
|
18 {
|
|
19 return CA1<T>() && requires () { typename T::ca2_type; };
|
|
20 }
|
|
21
|
|
22 template<typename T>
|
|
23 concept bool CA3()
|
|
24 {
|
|
25 return CA2<T>() && requires () { typename T::ca3_type; };
|
|
26 }
|
|
27
|
|
28 template<typename T>
|
|
29 concept bool CB1()
|
|
30 {
|
|
31 return requires () { typename T::cb1_type; };
|
|
32 }
|
|
33
|
|
34 template<typename T>
|
|
35 concept bool CB2()
|
|
36 {
|
|
37 return CB1<T>() && requires () { typename T::cb2_type; };
|
|
38 }
|
|
39
|
|
40 template<typename T>
|
|
41 concept bool CB3()
|
|
42 {
|
|
43 return CB2<T>() && requires () { typename T::cb3_type; };
|
|
44 }
|
|
45
|
|
46
|
|
47 struct MC { void mf(); };
|
|
48 static_assert(C<MC>(), "");
|
|
49
|
|
50
|
|
51 struct MA1 { using ca1_type = MC; };
|
|
52 struct MA2 : MA1 { using ca2_type = int; };
|
|
53 struct MA3 : MA2 { using ca3_type = int; };
|
|
54 static_assert(CA1<MA1>(), "");
|
|
55 static_assert(CA2<MA2>(), "");
|
|
56 static_assert(CA3<MA3>(), "");
|
|
57
|
|
58 struct MB1 { using cb1_type = int; };
|
|
59 struct MB2 : MB1 { using cb2_type = int; };
|
|
60 struct MB3 : MB2 { using cb3_type = int; };
|
|
61 static_assert(CB1<MB1>(), "");
|
|
62 static_assert(CB2<MB2>(), "");
|
|
63 static_assert(CB3<MB3>(), "");
|
|
64
|
|
65
|
|
66 template<typename T1, typename T2>
|
|
67 struct S;
|
|
68
|
|
69 template<CA1 T1, CB1 T2>
|
|
70 struct S<T1, T2> // Specialization #1
|
|
71 {
|
|
72 static constexpr int value = 1;
|
|
73 };
|
|
74
|
|
75 template<CA1 T1, CB2 T2>
|
|
76 requires !CA2<T1>()
|
|
77 struct S<T1, T2> // Specialization #2
|
|
78 {
|
|
79 static constexpr int value = 2;
|
|
80 };
|
|
81
|
|
82 template<CA2 T1, CB3 T2>
|
|
83 requires !CA3<T1>()
|
|
84 struct S<T1, T2> // Specialization #3
|
|
85 {
|
|
86 static constexpr int value = 3;
|
|
87 };
|
|
88
|
|
89 S<MA1,MB1> s11;
|
|
90 S<MA1,MB2> s12;
|
|
91 S<MA1,MB3> s13;
|
|
92 S<MA2,MB1> s21;
|
|
93 S<MA2,MB2> s22;
|
|
94 S<MA2,MB3> s23;
|
|
95 S<MA3,MB1> s31;
|
|
96 S<MA3,MB2> s32;
|
|
97 S<MA3,MB3> s33;
|
|
98
|
|
99 static_assert(S<MA1,MB1>::value == 1, "");
|
|
100 static_assert(S<MA1,MB2>::value == 2, "");
|
|
101 static_assert(S<MA1,MB3>::value == 2, "");
|
|
102 static_assert(S<MA2,MB1>::value == 1, "");
|
|
103 static_assert(S<MA2,MB2>::value == 1, "");
|
|
104 static_assert(S<MA2,MB3>::value == 3, "");
|
|
105 static_assert(S<MA3,MB1>::value == 1, "");
|
|
106 static_assert(S<MA3,MB2>::value == 1, "");
|
|
107 static_assert(S<MA3,MB3>::value == 1, "");
|