PR c++/85765 - SFINAE and non-type default template arg.
[official-gcc.git] / gcc / testsuite / g++.dg / cpp0x / alias-decl-50.C
blob6839d343e8a1128845a174120f7bfbc6d57fa62e
1 // PR c++/66067
2 // { dg-do compile { target c++11 } }
4 namespace std
6   typedef int size_t;
7     template < typename _Tp, _Tp > struct integral_constant
8   {
9     static constexpr _Tp value = 0;
10     typedef integral_constant type;
11   };
12   typedef integral_constant < int, 0 > true_type;
13   typedef integral_constant < int, 0 > false_type;
14     template < typename _Tp > struct enable_if
15   {
16     typedef _Tp type;
17   };
19 namespace meta
21   inline namespace v1
22   {
23     template < template < typename ... >class, typename ... >struct defer;
24       template < typename T > T * _nullptr_v (  );
25       template < int N > using size_t = std::integral_constant < int, N >;
26       template < int B > using bool_ = std::integral_constant < int, B >;
27       template < typename T > using dec =
28       std::integral_constant < decltype ( T::value ), 0 >;
29       template < typename T > using eval = typename T::type;
30       template < typename F, typename ... Args > using apply =
31       typename F::template apply < Args ... >;
32     namespace detail
33     {
34       template < typename > struct has_type_;
35     }
36     template < typename T > using has_type = eval < detail::has_type_ < T >>;
37       template < typename T > struct id
38     {
39       using type = T;
40     };
41       template < template < typename ... >class > struct quote;
42       template < typename > struct Trans_NS_extension_apply_list;
43       template < typename, typename List > using apply_list =
44       eval < Trans_NS_extension_apply_list < List >>;
45     namespace detail
46     {
47       template < typename ... >struct _if_;
48         template < typename If, typename Then > struct _if_ <If,
49         Then >:std::enable_if < Then >
50       {
51       };
52     }
53     template < typename ... Args > using if_ =
54       eval < detail::_if_ < Args ... >>;
55       template < int If, typename ... Args > using if_c =
56       eval < detail::_if_ < bool_ < If >, Args ... >>;
57     namespace detail
58     {
59       template < typename ... >struct _and_:std::true_type
60       {
61       };
62         template < typename ... >struct _or_:std::false_type
63       {
64       };
65     }
66     template < int >using not_c = bool_ < 0 >;
67       template < typename Bool > using not_ = not_c < Bool::value >;
68       template < typename ... >using and_ = eval < detail::_and_ <>>;
69       template < typename > using or_ = eval < detail::_or_ <>>;
70     namespace lazy
71     {
72       template < typename ... Bools > using and_ = defer < and_, Bools ... >;
73     }
74     template < typename ... Ts > struct list
75     {
76       static constexpr std::size_t size (  )
77       {
78         return sizeof ... ( Ts );
79       }
80     };
81       template < typename List > using size = size_t < List::size (  ) >;
82     namespace detail
83     {
84       template < typename > struct concat_;
85     }
86     template < typename ... Lists > using concat =
87       eval < detail::concat_ < Lists ... >>;
88       template < typename ListOfLists > using join =
89       apply_list < quote < concat >, ListOfLists >;
90     namespace detail
91     {
92       template < int >struct repeat_n_c_
93       {
94         using type = list <>;
95       };
96     }
97     template < typename > using repeat_n = eval < detail::repeat_n_c_ < 0 >>;
98       template < std::size_t N > using repeat_n_c =
99       eval < detail::repeat_n_c_ < N >>;
100     namespace detail
101     {
102       template < typename > struct at_impl_
103       {
104         template < typename T > static T eval ( T * );
105       };
106         template < typename, typename > struct at_;
107         template < typename ... Ts, typename N > struct at_ <list < Ts ... >,
108         N >:decltype ( at_impl_ < repeat_n <
109                        N >>::eval ( _nullptr_v < id < Ts >> (  )... ) )
110       {
111       };
112     }
113     template < typename List, typename N > using at =
114       eval < detail::at_ < List, N >>;
115     template < typename List, std::size_t > using at_c =
116       at < List, size_t < 0 >>;
117     namespace detail
118     {
119       template < typename > struct back_;
120         template < typename Head,
121         typename ... List > struct back_ <list < Head, List ... >>
122       {
123         using type = at_c < list < Head >, sizeof ... ( List ) >;
124       };
125     }
126     template < typename List > using back = eval < detail::back_ < List >>;
127     namespace detail
128     {
129       template < typename, typename > struct push_front_;
130         template < typename ... List,
131         typename T > struct push_front_ <list < List ... >, T >
132       {
133         using type = list < T >;
134       };
135     }
136     template < typename List, typename T > using push_front =
137       eval < detail::push_front_ < List, T >>;
138     namespace detail
139     {
140       template < typename > struct push_back_;
141     }
142     template < typename, typename T > using push_back =
143       eval < detail::push_back_ < T >>;
144     namespace detail
145     {
146       template < typename > struct transform_;
147     }
148     template < typename ... Args > using transform =
149       eval < detail::transform_ < Args ... >>;
150     namespace detail
151     {
152       template < typename > struct is_valid_;
153         template < typename As, typename Ts > using substitutions_ =
154         push_back < join < transform < concat < repeat_n_c < size < Ts >
155       {
156       }
157       >>>>, list < back < As >>>;
158       template < typename Ts > using substitutions =
159         apply < if_c < size < Ts >
160       {
161       }
162       , quote < substitutions_ >>>;
163       template < typename > struct is_vararg_:std::false_type
164       {
165       };
166       template < typename Tags > using is_variadic_ =
167         is_vararg_ < at < push_front < Tags, void >, dec < size < Tags >>>>;
168       template < typename Tags, int =
169         is_variadic_ < Tags >::value > struct lambda_;
170       template < typename ... As > struct lambda_ <list < As ... >, false >
171       {
172         using Tags = list < As ... >;
173         using F = back < Tags >;
174           template < typename, typename > struct impl;
175           template < typename, typename > struct subst_;
176           template < template < typename ... >class C, typename ... Ts,
177           typename Args > struct subst_ <defer < C, Ts ... >, Args >
178         {
179           using type = C < eval < impl < Ts, Args >> ... >;
180         };
181           template < template < typename ... >class C, typename ... Ts,
182           typename Args > struct impl <defer < C, Ts ... >,
183           Args >:subst_ < defer < C >, Args >
184         {
185         };
186           template < typename ... Ts > using apply =
187           eval < if_c < sizeof ... ( Ts ), impl < F, list <>>>>;
188       };
189     }
190     template < typename ... Ts > using lambda =
191       if_c < sizeof ... ( Ts ), detail::lambda_ < list < Ts ... >>>;
192     template < typename T > using is_valid = detail::is_valid_ < T >;
193     namespace detail
194     {
195       template < typename ... >struct let_;
196         template < typename Fn > struct let_ <Fn >
197       {
198         using type = apply < lambda < Fn >>;
199       };
200     }
201     template < typename ... As > using let = eval < detail::let_ < As ... >>;
202     template < typename > struct common_reference_base;
203     template < typename ... >struct common_reference;
204     namespace detail
205     {
206       template < typename > struct builtin_common_impl;
207         template < typename U > using builtin_common_t =
208         meta::apply < builtin_common_impl < U >>;
209         template < typename, typename > using lazy_builtin_common_t =
210         meta::defer < builtin_common_t >;
211         template < typename > struct transform_reference;
212         template < typename, typename U > using common_reference_base_ =
213         common_reference_base < meta::eval < transform_reference < U >>>;
214     }
215     template < typename T, typename U > struct common_reference <T,
216       U >:meta::if_ < meta::let < meta::lazy::and_ < meta::is_valid <
217       detail::lazy_builtin_common_t < T, U >>,
218       meta::or_ < meta::not_ < meta::has_type <
219       detail::common_reference_base_ < T, U >>>>>>,
220       detail::lazy_builtin_common_t < T, U >,
221       detail::common_reference_base_ < T, U >>
222     {
223     };
224   }