1// { dg-do compile }
2
3class Gmpfr
4{};
5class M : Gmpfr
6{
7public:
8  Gmpfr infconst;
9  M(int);
10};
11template<typename>struct A;
12template<typename, int, int, int = 0 ? : 0, int = 0, int = 0>class N;
13template<typename>class O;
14template<typename>struct B;
15struct C
16{
17  enum
18  { value };
19};
20class D
21{
22public:
23  enum
24  { ret };
25};
26struct F
27{
28  enum
29  { ret = 0 ? : 0 };
30};
31template<typename Derived>struct G
32{
33  typedef O<Derived>type;
34};
35struct H
36{
37  void operator * ();
38};
39struct I
40{
41  enum
42  { RequireInitialization = C::value ? : 0, ReadCost };
43};
44template<typename Derived>struct J
45{
46  enum
47  { ret = A<Derived>::InnerStrideAtCompileTime };
48};
49template<typename Derived>struct K
50{
51  enum
52  { ret = A<Derived>::OuterStrideAtCompileTime };
53};
54template<typename Derived>class P : H
55{
56public:
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
73template<typename Derived>class O : public P<Derived>
74{};
75
76template<int _Cols>class L
77{
78public:
79
80  int cols()
81  {
82    return _Cols;
83  }
84};
85template<typename Derived>class Q : public G<Derived>::type
86{
87public:
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;
92  Index cols()
93  {
94    return m_storage.cols();
95  }
96
97  Scalar& coeffRef(Index,
98                   Index);
99};
100
101template<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};
114template<typename _Scalar, int, int _Cols, int, int,
115         int>class N : public Q<N<_Scalar, 0, _Cols> >
116{
117public:
118  Q<N> Base;
119  template<typename T0, typename T1>N(const T0&,
120                                      const T1&);
121};
122void
123__assert_fail(int)
124throw() __attribute__((__noreturn__));
125template<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
158template<typename Derived>B<Derived>P<
159  Derived >::operator << (const Scalar&)
160{
161    return B<Derived>(*static_cast<Derived *>(this), 0);
162}
163
164template<class NT, int s>void
165               check_()
166{
167    N<NT, 0, s>m(0, 0);
168    m << 0, 0, 0, 0;
169}
170
171template<class NT>void check()
172{
173    check_<NT, 3>();
174}
175
176int main()
177{
178    check<M>();
179}
180