1// { dg-do compile }
2
3namespace std
4{
5  typedef __SIZE_TYPE__ size_t;
6}
7class H;
8namespace std
9{
10  template <typename> struct complex;
11  template <typename _Tp>
12      complex<_Tp> operator+(complex<_Tp> &__x, complex<_Tp> __y)
13	{
14	  complex<_Tp> a = __x;
15	  a += __y;
16	  return a;
17	}
18  template <> struct complex<double>
19    {
20      int
21	  imag ()
22	    {
23	      return __imag__ _M_value;
24	    }
25      void operator+=(complex __z) { _M_value += _M_value; _M_value  += __z.imag (); }
26      _Complex double _M_value;
27    };
28}
29struct A
30{
31  typedef std::complex<double> &const_reference;
32};
33class B
34{
35public:
36    B (int);
37    std::complex<double> &operator[](int i) { return data_[i]; }
38    std::complex<double> *data_;
39};
40struct C
41{
42  static std::complex<double>
43      apply (A::const_reference t1, std::complex<double> t2)
44	{
45	  return t1 + t2;
46	}
47  typedef std::complex<double> result_type;
48};
49template <class T1, class> struct D
50{
51  static void
52      apply (T1 t1, std::complex<double> t2)
53	{
54	  t1 = t2;
55	}
56};
57class ublas_expression
58{
59public:
60    ~ublas_expression ();
61};
62template <class> class F
63{
64};
65template <class E> class matrix_expression : ublas_expression
66{
67public:
68    E &operator()() {}
69};
70class I : public F<int>
71{
72public:
73    typedef int value_type;
74    I (int);
75};
76template <class E1, class E2> matrix_expression<int> outer_prod (F<E1>, F<E2>);
77template <class E1, class F> class J : public matrix_expression<J<E1, F> >
78{
79public:
80    typedef typename F::result_type value_type;
81    value_type operator()(int i, int)
82      {
83	return F::apply (e1_ (i, 0), e2_ (0, 0));
84      }
85    E1 e1_;
86    E1 e2_;
87};
88template <class E1, class E2>
89J<H, C> operator+(matrix_expression<E1>, matrix_expression<E2>);
90template <template <class, class> class F, class M, class E>
91void
92indexing_matrix_assign (M m, matrix_expression<E> e, int)
93{
94  for (int i; i; ++i)
95    F<typename M::reference, typename E::value_type>::apply (m (0, 0),
96							     e ()(i, 0));
97}
98template <template <class, class> class F, class, class M, class E, class C>
99void
100matrix_assign (M m, matrix_expression<E> e, int, C)
101{
102  indexing_matrix_assign<F> (m, e, 0);
103}
104template <template <class, class> class F, class M, class E>
105void
106matrix_assign (M m, matrix_expression<E> e)
107{
108  matrix_assign<F, int> (m, e, 0, typename M::orientation_category ());
109}
110class H : matrix_expression<int>
111{
112public:
113    typedef std::complex<double> &reference;
114    typedef int orientation_category;
115    H (int, int) : data_ (0) {}
116    template <class AE> H (matrix_expression<AE> ae) : data_ (0)
117  {
118    matrix_assign<D> (*this, ae);
119  }
120    B &
121	data ()
122	  {
123	  }
124    std::complex<double> &operator()(int i, int) { return data ()[i]; }
125    void operator+=(matrix_expression ae) { H (*this + ae); }
126    B data_;
127};
128template <class M, class T, class V1, class V2>
129void
130sr2 (M m, T, V1 v1, V2 v2)
131{
132  m += outer_prod (v2, v1);
133}
134template <class, class, std::size_t> struct G
135{
136  void test ();
137};
138template struct G<I, H, 3>;
139template <class V, class M, std::size_t N>
140void
141G<V, M, N>::test ()
142{
143  V b (0), c (0);
144  M m (0, 0);
145  sr2 (m, typename V::value_type (), b, c);
146}
147