1 // { dg-do compile }
2 
3 class Gmpfr
4 {};
5 class M : Gmpfr
6 {
7 public:
8   Gmpfr infconst;
9   M(int);
10 };
11 template<typename>struct A;
12 template<typename, int, int, int = 0 ? : 0, int = 0, int = 0>class N;
13 template<typename>class O;
14 template<typename>struct B;
15 struct C
16 {
17   enum
18   { value };
19 };
20 class D
21 {
22 public:
23   enum
24   { ret };
25 };
26 struct F
27 {
28   enum
29   { ret = 0 ? : 0 };
30 };
31 template<typename Derived>struct G
32 {
33   typedef O<Derived>type;
34 };
35 struct H
36 {
37   void operator * ();
38 };
39 struct I
40 {
41   enum
42   { RequireInitialization = C::value ? : 0, ReadCost };
43 };
44 template<typename Derived>struct J
45 {
46   enum
47   { ret = A<Derived>::InnerStrideAtCompileTime };
48 };
49 template<typename Derived>struct K
50 {
51   enum
52   { ret = A<Derived>::OuterStrideAtCompileTime };
53 };
54 template<typename Derived>class P : H
55 {
56 public:
57   using H::operator *;
58   typedef typename A<Derived>::Scalar Scalar;
59   enum
60   { RowsAtCompileTime                                        =
61       A<Derived>::RowsAtCompileTime, ColsAtCompileTime       =
62       A<Derived>::ColsAtCompileTime, SizeAtCompileTime       =
63       F::ret, MaxRowsAtCompileTime                           =
64       A<Derived>::MaxRowsAtCompileTime, MaxColsAtCompileTime =
65       A<Derived>::MaxColsAtCompileTime, MaxSizeAtCompileTime =
66       F::ret, Flags                                          =
67       A<Derived>::Flags ? : 0 ? : 0, CoeffReadCost           =
68       A<Derived>::CoeffReadCost, InnerStrideAtCompileTime    =
69       J<Derived>::ret, OuterStrideAtCompileTime              = K<Derived>::ret };
70   B<Derived> operator << (const Scalar&);
71 };
72 
73 template<typename Derived>class O : public P<Derived>
74 {};
75 
76 template<int _Cols>class L
77 {
78 public:
79 
cols()80   int cols()
81   {
82     return _Cols;
83   }
84 };
85 template<typename Derived>class Q : public G<Derived>::type
86 {
87 public:
88   typedef typename G<Derived>::type   Base;
89   typedef typename A<Derived>::Index  Index;
90   typedef typename A<Derived>::Scalar Scalar;
91   L<Base::ColsAtCompileTime> m_storage;
cols()92   Index cols()
93   {
94     return m_storage.cols();
95   }
96 
97   Scalar& coeffRef(Index,
98                    Index);
99 };
100 
101 template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
102          int _MaxCols>struct A<N<_Scalar, _Rows, _Cols, _Options, _MaxRows,
103                                  _MaxCols> >
104 {
105   typedef _Scalar Scalar;
106   typedef int     Index;
107   enum
108   { RowsAtCompileTime, ColsAtCompileTime                              =
109       _Cols, MaxRowsAtCompileTime, MaxColsAtCompileTime, Flags        =
110       D::ret, CoeffReadCost                                           =
111       I::ReadCost, InnerStrideAtCompileTime, OuterStrideAtCompileTime =
112       0 ? : 0 };
113 };
114 template<typename _Scalar, int, int _Cols, int, int,
115          int>class N : public Q<N<_Scalar, 0, _Cols> >
116 {
117 public:
118   Q<N> Base;
119   template<typename T0, typename T1>N(const T0&,
120                                       const T1&);
121 };
122 void
123 __assert_fail(int)
124 throw() __attribute__((__noreturn__));
125 template<typename XprType>struct B
126 {
127   typedef typename XprType::Scalar Scalar;
128   typedef typename XprType::Index  Index;
129   B(XprType & p1, const Scalar &) : m_xpr(p1), m_col(),
130                                     m_currentBlockRows(1)
131   {} B& operator, (const Scalar&)
132   {
133     Index a;
134 
135     if (m_col == m_xpr.cols())
136     {
137       m_col              = 0;
138       m_currentBlockRows = 1;
139       a && "Too       " ? static_cast<void>(0) : __assert_fail(0);
140     }
141     m_col < m_xpr.cols()
142     && "Too       " ? static_cast<void>(0) : __assert_fail(1);
143     m_currentBlockRows ? static_cast<void>(0) : __assert_fail(4);
144     m_xpr.coeffRef(0, m_col++) = 0;
145     return *this;
146   }
147   ~B()
148   {
149     1 + m_currentBlockRows && m_col
150     && "Too       " ? static_cast<void>(0) : __assert_fail(0);
151   }
152 
153   XprType& m_xpr;
154   Index    m_col;
155   Index    m_currentBlockRows;
156 };
157 
158 template<typename Derived>B<Derived>P<
159   Derived >::operator << (const Scalar&)
160 {
161     return B<Derived>(*static_cast<Derived *>(this), 0);
162 }
163 
164 template<class NT, int s>void
165                check_()
166 {
167     N<NT, 0, s>m(0, 0);
168     m << 0, 0, 0, 0;
169 }
170 
171 template<class NT>void check()
172 {
173     check_<NT, 3>();
174 }
175 
176 int main()
177 {
178     check<M>();
179 }
180