comparison gcc/testsuite/g++.dg/cpp0x/variadic-alias2.C @ 152:2b5abeee2509

update gcc11
author anatofuz
date Mon, 25 May 2020 07:50:57 +0900
parents
children
comparison
equal deleted inserted replaced
145:1830386684a0 152:2b5abeee2509
1 // PR c++/91966
2 // { dg-do compile { target c++11 } }
3
4 // Reduced to this include-free example. Further reduction is hard: Either
5 // the bug(?) disappears, or the program becomes meaningless.
6
7 template<class...>
8 struct list {};
9
10 struct nil;
11
12 ////////////////////////////////////////////////////////////////////////////////
13
14 template<int n>
15 struct number {
16 constexpr /*implicit*/ operator int() const { return n; }
17 using type = number<n>;
18 };
19
20 using false_ = number<0>;
21 using true_ = number<1>;
22
23 static_assert(!false_{}, "");
24 static_assert(true_{}, "");
25
26 template<int... ns> using numbers = list<number<ns>...>;
27
28 ////////////////////////////////////////////////////////////////////////////////
29
30 template<class lhs, class rhs>
31 struct less_impl;
32
33 template<int lhs, int rhs>
34 struct less_impl<number<lhs>, number<rhs>>
35 : number<(lhs < rhs)> {};
36
37 template<class lhs, class rhs> using less = typename less_impl<lhs, rhs>::type;
38
39 ////////////////////////////////////////////////////////////////////////////////
40
41 template<class v0, class... vs>
42 struct sum_impl {
43 static_assert(sizeof...(vs) == 0, "see specialization");
44 using type = v0;
45 };
46
47 template<int v0, int v1, class... vs>
48 struct sum_impl<number<v0>, number<v1>, vs...>
49 : sum_impl<number<v0 + v1>, vs...> {};
50
51 template<class... nums> using sum = typename sum_impl<nums...>::type;
52
53 ////////////////////////////////////////////////////////////////////////////////
54
55 template<class num>
56 struct conditional_impl {
57 static_assert(num{}, "see specialization");
58
59 template<class T, class F>
60 using type = T;
61 };
62
63 template<>
64 struct conditional_impl<false_> {
65 template<class T, class F>
66 using type = F;
67 };
68
69 template<class num, class T, class F>
70 using conditional = typename conditional_impl<num>::template type<T, F>;
71
72 ////////////////////////////////////////////////////////////////////////////////
73
74 template<class seq>
75 struct min_filter_impl;
76
77 template<class... nums>
78 struct min_filter_impl<list<nums...>> {
79 template<class num>
80 using count_better_mins = sum<less<nums, num>...>;
81
82 using type = list<conditional<count_better_mins<nums>, nil, nums>...>;
83
84 //using debug = list<conditional<count_better_mins<nums>, nil, void>...>;
85
86 // error: expansion pattern 'conditional<typename sum_impl<less<nums, nums>...>::type, nil, void>' contains no parameter packs
87
88 };
89
90 template<class seq> using min_filter = typename min_filter_impl<seq>::type;
91
92 ////////////////////////////////////////////////////////////////////////////////
93
94 void test_min_filter() {
95 using computed = min_filter<numbers<2, 7, 2>>;
96 using expected = list<number<2>, nil, number<2>>;
97 (void)(computed{} = expected{});// compiles for identical types
98
99 // error: no match for 'operator=' (operand types are 'computed' {aka 'list<number<2>, number<7>, number<2> >'} and 'expected' {aka 'list<number<2>, nil, number<2> >'})
100
101 }
102
103 int main() {}