1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the test suite module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file. Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights. These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 #include <QtCore/QtDebug>
44 #include <QtCore/QList>
51 #define QLALR_NO_CHECK_SORTED_TABLE
53 struct _Fit
: public std::binary_function
<int, int, bool>
55 inline bool operator () (int a
, int b
) const
57 return a
== 0 || b
== 0 || a
== b
;
61 struct _PerfectMatch
: public std::binary_function
<int, int, bool>
63 inline bool operator () (int a
, int b
) const
69 QVector
<int>::const_iterator iterator
;
72 _GenerateCheck (QVector
<int>::const_iterator it
, int i
):
76 inline int operator () ()
78 int check
= initial
++;
79 return *iterator
++ ? check
: -1;
86 typedef const int *const_iterator
;
87 typedef const int *iterator
;
90 inline UncompressedRow ():
97 inline UncompressedRow (int index
, const_iterator begin
, const_iterator end
)
98 { assign (index
, begin
, end
); }
100 inline int index () const { return _M_index
; }
101 inline const_iterator
begin () const { return _M_begin
; }
102 inline const_iterator
end () const { return _M_end
; }
104 inline void assign (int index
, const_iterator begin
, const_iterator end
)
110 _M_beginNonZeros
= _M_begin
;
111 _M_endNonZeros
= _M_end
;
113 for (_M_beginNonZeros
= _M_begin
; _M_beginNonZeros
!= _M_end
&& ! _M_beginNonZeros
[0]; ++_M_beginNonZeros
)
117 for (_M_endNonZeros
= _M_end
; _M_endNonZeros
!= _M_beginNonZeros
&& ! _M_endNonZeros
[-1]; --_M_endNonZeros
)
122 inline int at (int index
) const
123 { return _M_begin
[index
]; }
125 inline bool isEmpty () const
126 { return _M_begin
== _M_end
; }
128 inline int size () const
129 { return _M_end
- _M_begin
; }
131 inline int nonZeroElements () const
132 { return _M_endNonZeros
- _M_beginNonZeros
; }
134 inline int count (int value
) const
135 { return std::count (begin (), end (), value
); }
137 inline const_iterator
beginNonZeros () const
138 { return _M_beginNonZeros
; }
140 inline const_iterator
endNonZeros () const
141 { return _M_endNonZeros
; }
145 const_iterator _M_begin
;
146 const_iterator _M_end
;
147 const_iterator _M_beginNonZeros
;
148 const_iterator _M_endNonZeros
;
151 struct _SortUncompressedRow
: public std::binary_function
<UncompressedRow
, UncompressedRow
, bool>
153 inline bool operator () (const UncompressedRow
&a
, const UncompressedRow
&b
) const
154 { return a
.count (0) > b
.count (0); }
157 Compress::Compress ()
161 void Compress::operator () (int *table
, int row_count
, int column_count
)
167 QVector
<UncompressedRow
> sortedTable (row_count
);
169 for (int i
= 0; i
< row_count
; ++i
)
171 int *begin
= &table
[i
* column_count
];
172 int *end
= begin
+ column_count
;
174 sortedTable
[i
].assign (i
, begin
, end
);
177 qSort (sortedTable
.begin (), sortedTable
.end (), _SortUncompressedRow ());
179 #ifndef QLALR_NO_CHECK_SORTED_TABLE
180 int previous_zeros
= INT_MAX
;
182 foreach (UncompressedRow row
, sortedTable
)
184 int zeros
= row
.count (0);
186 Q_ASSERT (zeros
<= previous_zeros
);
187 zeros
= previous_zeros
;
192 index
.fill (-999999, row_count
);
194 foreach (UncompressedRow row
, sortedTable
)
196 int first_token
= std::distance (row
.begin (), row
.beginNonZeros ());
197 QVector
<int>::iterator pos
= info
.begin ();
199 while (pos
!= info
.end ())
201 if (pos
== info
.begin ())
203 // try to find a perfect match
204 QVector
<int>::iterator pm
= std::search (pos
, info
.end (), row
.beginNonZeros (), row
.endNonZeros (), _PerfectMatch ());
206 if (pm
!= info
.end ())
213 pos
= std::search (pos
, info
.end (), row
.beginNonZeros (), row
.endNonZeros (), _Fit ());
215 if (pos
== info
.end ())
218 int idx
= std::distance (info
.begin (), pos
) - first_token
;
219 bool conflict
= false;
221 for (int j
= 0; ! conflict
&& j
< row
.size (); ++j
)
224 conflict
|= idx
+ j
>= 0 && check
[idx
+ j
] == j
;
227 conflict
|= check
[idx
+ j
] == j
;
236 if (pos
== info
.end ())
238 int size
= info
.size ();
240 info
.resize (info
.size () + row
.nonZeroElements ());
241 check
.resize (info
.size ());
243 std::fill (check
.begin () + size
, check
.end (), -1);
244 pos
= info
.begin () + size
;
247 int offset
= std::distance (info
.begin (), pos
);
248 index
[row
.index ()] = offset
- first_token
;
250 for (const int *it
= row
.beginNonZeros (); it
!= row
.endNonZeros (); ++it
, ++pos
)
256 int i
= row
.index ();
258 for (int j
= 0; j
< row
.size (); ++j
)
263 check
[index
[i
] + j
] = j
;
268 foreach (UncompressedRow row
, sortedTable
)
270 int i
= row
.index ();
271 Q_ASSERT (i
< sortedTable
.size ());
273 for (int j
= 0; j
< row
.size (); ++j
)
277 Q_ASSERT (index
[i
] + j
< 0 || check
[index
[i
] + j
] != j
);
281 Q_ASSERT ( info
[index
[i
] + j
] == row
.at (j
));
282 Q_ASSERT (check
[index
[i
] + j
] == j
);