1// { dg-do compile }
2
3template <typename C> struct A
4{
5  typedef typename C::iterator type;
6};
7template <typename T2> struct B
8{
9  typedef T2 type;
10};
11template <typename F2> struct L
12{
13  typedef typename B<F2>::type::type type;
14};
15template <typename C> struct M
16{
17  typedef typename L<A<C> >::type type;
18};
19class C
20{
21public:
22  typedef int iterator;
23};
24template <class IteratorT> class D
25{
26public:
27  typedef IteratorT iterator;
28  template <class Iterator> D (Iterator p1, Iterator) : m_Begin (p1), m_End (0)
29  {
30  }
31  IteratorT m_Begin;
32  IteratorT m_End;
33};
34template <class IteratorT> class I : public D<IteratorT>
35{
36protected:
37  template <class Iterator>
38  I (Iterator p1, Iterator p2)
39      : D<IteratorT> (p1, p2)
40  {
41  }
42};
43class F
44{
45public:
46  int elems[];
47  int *
48  m_fn1 ()
49  {
50    return elems;
51  }
52};
53class G
54{
55public:
56  void *
57  m_fn2 (int)
58  {
59    return m_buffer.m_fn1 ();
60  }
61  F m_buffer;
62};
63struct any_incrementable_iterator_interface
64{
65  virtual ~any_incrementable_iterator_interface () {}
66};
67class J : public any_incrementable_iterator_interface
68{
69public:
70  J (int) : m_it () {}
71  int m_it;
72};
73void *operator new(__SIZE_TYPE__, void *p2) { return p2; }
74template <class T> typename M<T>::type begin (T) { return 0; }
75template <class T> typename M<T>::type end (T) {}
76template <class> class any_iterator
77{
78public:
79  template <class WrappedIterator> any_iterator (WrappedIterator)
80  {
81    void *ptr = m_buffer.m_fn2 (0);
82    m_impl = new (ptr) J (0);
83  }
84  ~any_iterator ()
85  {
86    if (m_impl)
87      m_impl->~any_incrementable_iterator_interface ();
88  }
89  G m_buffer;
90  any_incrementable_iterator_interface *m_impl;
91};
92template <class Reference> class K : public I<any_iterator<Reference> >
93{
94public:
95  template <class WrappedRange>
96  K (WrappedRange p1)
97      : I<any_iterator<Reference> > (begin (p1), end (p1))
98  {
99  }
100};
101template <class Reference> struct H
102{
103  typedef K<Reference> type;
104};
105template <class, class, class, class, class, class TargetReference>
106void
107mix_values_impl ()
108{
109  C test_data;
110  H<int>::type source_data (test_data);
111  typename H<TargetReference>::type t2 = source_data;
112}
113template <class>
114void
115mix_values_driver ()
116{
117  mix_values_impl<int, int, int, int, int, int &> ();
118}
119void
120mix_values ()
121{
122  mix_values_driver<int> ();
123}
124