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