1// PR c++/66387 2// { dg-do compile { target c++14 } } 3 4namespace boost { 5namespace hana { 6namespace detail { 7namespace std { 8using size_t = decltype(0); 9} 10} 11namespace ic_detail { 12template <typename T, T> struct _with_index { 13 template <typename F> constexpr void operator()(F &&) const; 14}; 15template <typename T, T v> struct _times { _with_index<T, v> with_index; }; 16} 17template <typename T, T v> struct _integral_constant { 18 using value_type = T; 19 operator value_type() const; 20 ic_detail::_times<T, v> times; 21}; 22template <detail::std::size_t i> 23constexpr _integral_constant<detail::std::size_t, i> size_t{}; 24template <typename, typename = void> struct datatype; 25} 26} 27namespace std { 28typedef int size_t; 29inline namespace __cxx11 {} 30} 31namespace boost { 32namespace hana { 33template <bool> struct when; 34template <typename, typename, typename> struct to_impl; 35template <typename T, typename> struct datatype : datatype<T, when<true>> {}; 36template <typename T, bool condition> struct datatype<T, when<condition>> { 37 using type = typename T::hana::datatype; 38}; 39template <typename> struct _models; 40template <typename To, typename From> 41 struct to_impl < To, 42 From, when < _models<From> { 43} >> ; 44namespace detail { 45namespace std { 46template <typename T, T> struct integer_sequence; 47template <size_t... n> using index_sequence = integer_sequence<size_t, n...>; 48namespace int_seq_detail { 49template <size_t> struct make_index_sequence { 50 using type = index_sequence<0>; 51}; 52template <typename, typename> struct cast_to; 53template <typename T, typename U, U... u> 54struct cast_to<T, integer_sequence<U, u...>> { 55 using type = integer_sequence<T, u...>; 56}; 57} 58template <typename T, T> 59using make_integer_sequence = typename int_seq_detail::cast_to< 60 T, int_seq_detail::make_index_sequence<1>::type>::type; 61} 62} 63namespace ic_detail { 64template <typename T, T N, typename = detail::std::make_integer_sequence<T, N>> 65struct go; 66template <typename T, T N, T... i> 67struct go<T, N, detail::std::integer_sequence<T, i...>> { 68 using swallow = T; 69 template <typename F> static void with_index(F f) { 70 swallow{(f(_integral_constant<T, i>{}), 0)...}; 71 } 72}; 73template <typename T, T v> 74template <typename F> 75constexpr void _with_index<T, v>::operator()(F &&f) const { 76 go<T, 0>::with_index(f); 77} 78} 79} 80} 81namespace std { 82template <typename> class allocator; 83template <class> struct char_traits; 84template <typename _CharT, typename = char_traits<_CharT>> class basic_ostream; 85namespace __cxx11 { 86template <typename _CharT, typename = char_traits<_CharT>, 87 typename = allocator<_CharT>> 88class basic_stringstream; 89} 90typedef basic_ostream<char> ostream; 91typedef basic_stringstream<char> stringstream; 92template <typename, typename> class basic_ostream {}; 93template <typename _CharT, typename> 94class basic_iostream : public basic_ostream<_CharT> {}; 95namespace __cxx11 { 96template <typename _CharT, typename _Traits, typename> 97class basic_stringstream : public basic_iostream<_CharT, _Traits> {}; 98} 99} 100namespace hana = boost::hana; 101template <typename> struct print_impl; 102template <typename X> void print(std::ostream os, X x) { 103 using Tag = typename hana::datatype<X>::type; 104 print_impl<Tag>::apply(os, x); 105} 106struct Vector; 107template <typename, typename> struct vector2 { 108 struct hana { 109 using datatype = Vector; 110 }; 111 static constexpr std::size_t size = 0; 112}; 113template <> struct print_impl<Vector> { 114 template <typename vectorN> static void apply(std::ostream, vectorN) { 115 constexpr auto N = hana::size_t<vectorN::size>; 116 N.times.with_index([&](auto) { N - hana::size_t<1>; }); 117 } 118}; 119int main() { 120 std::stringstream ss; 121 vector2<int, char> v2; 122 print(ss, v2); 123} 124