ipa-cp: Perform operations in the appropriate types (PR 118097)
[gcc.git] / gcc / testsuite / g++.dg / concepts / pr65681.C
blob9a4615d61b901b9c5c549f5347035cdb2e5a7d11
1 // { dg-do compile { target c++17 } }
2 // { dg-options "-fconcepts" }
4 template<typename T>
5 concept C = requires (T t) { t.mf(); };
7 template<typename T>
8 concept CA1 = C<typename T::ca1_type>;
10 template<typename T>
11 concept CA2 = CA1<T> && requires () { typename T::ca2_type; };
13 template<typename T>
14 concept CA3 = CA2<T> && requires () { typename T::ca3_type; };
16 template<typename T>
17 concept CB1 = requires () { typename T::cb1_type; };
19 template<typename T>
20 concept CB2 = CB1<T> && requires () { typename T::cb2_type; };
22 template<typename T>
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>
46 struct S;
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>
55   requires (!CA2<T1>)
56 struct S<T1, T2> // Specialization #2
58   static constexpr int value = 2;
61 template<CA2 T1, CB3 T2>
62   requires (!CA3<T1>)
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, "");