1 // { dg-do compile }
2 // { dg-additional-options "-std=c++11" }
3 
4 namespace std
5 {
6 typedef long unsigned size_t;
7 template <typename> class complex;
8 template <typename _Tp> complex<_Tp> operator+(complex<_Tp>, complex<_Tp>)
9 {
10   complex<_Tp> a = 0;
11   a += 0;
12   return a;
13 }
14 template <> struct complex<double>
15 {
16   complex (int __i) : _M_value{ __i } {}
17   int imag ();
18   void operator+=(complex __z) { _M_value = __z.imag (); }
19   _Complex double _M_value;
20 };
21 }
22 class A
23 {
24 public:
25   A (int);
26   std::complex<double> &operator[](int i) { return data_[i]; }
27   std::complex<double> *data_;
28 };
29 struct B
30 {
31   static std::complex<double>
32   apply (std::complex<double> t1, std::complex<double> t2)
33   {
34     return t1 + t2;
35   }
36 };
37 template <class T1, class> struct C
38 {
39   static void
40   apply (T1 t1, std::complex<double> t2)
41   {
42     t1 = t2;
43   }
44 };
45 template <class E> class D
46 {
47 public:
48   E operator()();
49 };
50 class G : public D<G>
51 {
52 public:
53   typedef std::complex<double> value_type;
54   value_type operator()(int) { return B::apply (0, 0); }
55 };
56 template <class E1, class E2> G operator+(D<E1>, D<E2>);
57 template <template <class, class> class F, class V, class E>
58 void
59 indexing_vector_assign (V v, D<E> e)
60 {
61   for (int i;; ++i)
62     F<typename V::reference, typename E::value_type>::apply (v (i), e ()(0));
63 }
64 template <template <class, class> class F, class V, class E>
65 void
66 vector_assign (V v, D<E> e, int)
67 {
68   indexing_vector_assign<F> (v, e);
69 }
70 template <template <class, class> class F, class V, class E>
71 void
72 vector_assign (V v, D<E> e)
73 {
74   vector_assign<F> (v, e, typename V::storage_category ());
75 }
76 class H : public D<int>
77 {
78 public:
79   typedef std::complex<double> &reference;
80   typedef int storage_category;
81   H (int);
82   template <class AE> H (D<AE> ae) : data_ (0)
83   {
84     vector_assign<C> (*this, ae);
85   }
86   A
87   data ()
88   {
89     return data_;
90   }
91   reference operator()(int i) { return data ()[i]; }
92   A data_;
93 };
94 template <class T1, class V1, class T2, class V2>
95 void
96 rot (T1, V1 v1, T2, V2 v2)
97 {
98   H (v1 + v2);
99 }
100 template <class, unsigned long> struct F
101 {
102   void test ();
103 };
104 template struct F<H, 3>;
105 template <class V, std::size_t N>
106 void
107 F<V, N>::test ()
108 {
109   V b (0), c (0);
110   rot (0, b, 0, c);
111 }
112