1 // PR c++/66067 2 // { dg-do compile { target c++11 } } 3 4 namespace std 5 { 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 }; 18 } 19 namespace meta 20 { 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 } 225 } 226