QtBase  v6.3.1
tst_bench_qstring.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 #include <QStringList>
29 #include <QFile>
30 #include <QTest>
31 #include <limits>
32 
33 class tst_QString: public QObject
34 {
35  Q_OBJECT
36 public:
38 private slots:
39  void section_regexp_data() { section_data_impl(); }
40  void section_regularexpression_data() { section_data_impl(); }
41  void section_regularexpression() { section_impl<QRegularExpression>(); }
42  void section_string_data() { section_data_impl(false); }
43  void section_string() { section_impl<QString>(); }
44 
45  void toUpper_data();
46  void toUpper();
47  void toLower_data();
48  void toLower();
49  void toCaseFolded_data();
50  void toCaseFolded();
51 
52  void number_qlonglong_data();
53  void number_qlonglong() { number_impl<qlonglong>(); }
54  void number_qulonglong_data();
55  void number_qulonglong() { number_impl<qulonglong>(); }
56 
57  void number_double_data();
58  void number_double();
59 
60 private:
61  void section_data_impl(bool includeRegExOnly = true);
62  template <typename RX> void section_impl();
63  template <typename Integer> void number_impl();
64 };
65 
67 {
68 }
69 
70 void tst_QString::section_data_impl(bool includeRegExOnly)
71 {
72  QTest::addColumn<QString>("s");
73  QTest::addColumn<QString>("sep");
74  QTest::addColumn<bool>("isRegExp");
75 
76  QTest::newRow("IPv4") << QStringLiteral("192.168.0.1") << QStringLiteral(".") << false;
77  QTest::newRow("IPv6") << QStringLiteral("2001:0db8:85a3:0000:0000:8a2e:0370:7334") << QStringLiteral(":") << false;
78  if (includeRegExOnly) {
79  QTest::newRow("IPv6-reversed-roles") << QStringLiteral("2001:0db8:85a3:0000:0000:8a2e:0370:7334") << QStringLiteral("\\d+") << true;
80  QTest::newRow("IPv6-complex") << QStringLiteral("2001:0db8:85a3:0000:0000:8a2e:0370:7334") << QStringLiteral("(\\d+):\\1") << true;
81  }
82 }
83 
84 template <typename RX>
85 inline QString escape(const QString &s)
86 { return RX::escape(s); }
87 
88 template <>
90 { return s; }
91 
92 template <typename RX>
93 inline void optimize(RX &) {}
94 
95 template <>
97 { rx.optimize(); }
98 
99 template <typename RX>
100 void tst_QString::section_impl()
101 {
102  QFETCH(QString, s);
103  QFETCH(QString, sep);
104  QFETCH(bool, isRegExp);
105 
106  RX rx(isRegExp ? sep : escape<RX>(sep));
107  optimize(rx);
108  for (int i = 0; i < 20; ++i)
109  (void) s.count(rx); // make (s, rx) hot
110 
111  QBENCHMARK {
112  const QString result = s.section(rx, 0, 16);
113  Q_UNUSED(result);
114  }
115 }
116 
117 void tst_QString::toUpper_data()
118 {
119  QTest::addColumn<QString>("s");
120 
121  QString lowerLatin1(300, QChar('a'));
122  QString upperLatin1(300, QChar('A'));
123 
124  QString lowerDeseret;
125  {
127  pattern += QChar(QChar::highSurrogate(0x10428));
128  pattern += QChar(QChar::lowSurrogate(0x10428));
129  for (int i = 0; i < 300 / pattern.size(); ++i)
130  lowerDeseret += pattern;
131  }
132  QString upperDeseret;
133  {
135  pattern += QChar(QChar::highSurrogate(0x10400));
136  pattern += QChar(QChar::lowSurrogate(0x10400));
137  for (int i = 0; i < 300 / pattern.size(); ++i)
138  upperDeseret += pattern;
139  }
140 
141  QString lowerLigature(600, QChar(0xFB03));
142 
143  QTest::newRow("600<a>") << (lowerLatin1 + lowerLatin1);
144  QTest::newRow("600<A>") << (upperLatin1 + upperLatin1);
145 
146  QTest::newRow("300<a>+300<A>") << (lowerLatin1 + upperLatin1);
147  QTest::newRow("300<A>+300<a>") << (upperLatin1 + lowerLatin1);
148 
149  QTest::newRow("300<10428>") << (lowerDeseret + lowerDeseret);
150  QTest::newRow("300<10400>") << (upperDeseret + upperDeseret);
151 
152  QTest::newRow("150<10428>+150<10400>") << (lowerDeseret + upperDeseret);
153  QTest::newRow("150<10400>+150<10428>") << (upperDeseret + lowerDeseret);
154 
155  QTest::newRow("300a+150<10400>") << (lowerLatin1 + upperDeseret);
156  QTest::newRow("300a+150<10428>") << (lowerLatin1 + lowerDeseret);
157  QTest::newRow("300A+150<10400>") << (upperLatin1 + upperDeseret);
158  QTest::newRow("300A+150<10428>") << (upperLatin1 + lowerDeseret);
159 
160  QTest::newRow("600<FB03> (ligature)") << lowerLigature;
161 }
162 
163 void tst_QString::toUpper()
164 {
165  QFETCH(QString, s);
166 
167  QBENCHMARK {
168  [[maybe_unused]] auto r = s.toUpper();
169  }
170 }
171 
172 void tst_QString::toLower_data()
173 {
174  toUpper_data();
175 }
176 
177 void tst_QString::toLower()
178 {
179  QFETCH(QString, s);
180 
181  QBENCHMARK {
182  [[maybe_unused]] auto r = s.toLower();
183  }
184 }
185 
186 void tst_QString::toCaseFolded_data()
187 {
188  toUpper_data();
189 }
190 
191 void tst_QString::toCaseFolded()
192 {
193  QFETCH(QString, s);
194 
195  QBENCHMARK {
196  [[maybe_unused]] auto r = s.toCaseFolded();
197  }
198 }
199 
200 template <typename Integer>
201 void tst_QString::number_impl()
202 {
203  QFETCH(Integer, number);
204  QFETCH(int, base);
205  QFETCH(QString, expected);
206 
207  QString actual;
208  QBENCHMARK {
209  actual = QString::number(number, base);
210  }
211  QCOMPARE(actual, expected);
212 }
213 
214 template <typename Integer>
216 {
217  QTest::newRow("0") << Integer(0ull) << 10 << QStringLiteral("0");
218  QTest::newRow("1234") << Integer(1234ull) << 10 << QStringLiteral("1234");
219  QTest::newRow("123456789") << Integer(123456789ull) << 10 << QStringLiteral("123456789");
220  QTest::newRow("bad1dea, base 16") << Integer(0xBAD1DEAull) << 16 << QStringLiteral("bad1dea");
221  QTest::newRow("242, base 8") << Integer(0242ull) << 8 << QStringLiteral("242");
222  QTest::newRow("101101, base 2") << Integer(0b101101ull) << 2 << QStringLiteral("101101");
223  QTest::newRow("ad, base 30") << Integer(313ull) << 30 << QStringLiteral("ad");
224 }
225 
226 void tst_QString::number_qlonglong_data()
227 {
228  QTest::addColumn<qlonglong>("number");
229  QTest::addColumn<int>("base");
230  QTest::addColumn<QString>("expected");
231 
232  number_integer_common<qlonglong>();
233 
234  QTest::newRow("-1234") << -1234ll << 10 << QStringLiteral("-1234");
235  QTest::newRow("-123456789") << -123456789ll << 10 << QStringLiteral("-123456789");
236  QTest::newRow("-bad1dea, base 16") << -0xBAD1DEAll << 16 << QStringLiteral("-bad1dea");
237  QTest::newRow("-242, base 8") << -0242ll << 8 << QStringLiteral("-242");
238  QTest::newRow("-101101, base 2") << -0b101101ll << 2 << QStringLiteral("-101101");
239  QTest::newRow("-ad, base 30") << -313ll << 30 << QStringLiteral("-ad");
240 
241  QTest::newRow("qlonglong-max")
242  << std::numeric_limits<qlonglong>::max() << 10 << QStringLiteral("9223372036854775807");
243  QTest::newRow("qlonglong-min")
244  << std::numeric_limits<qlonglong>::min() << 10
245  << QStringLiteral("-9223372036854775808");
246  QTest::newRow("qlonglong-max, base 2")
247  << std::numeric_limits<qlonglong>::max() << 2 << QString(63, u'1');
248  QTest::newRow("qlonglong-min, base 2") << std::numeric_limits<qlonglong>::min() << 2
249  << (QStringLiteral("-1") + QString(63, u'0'));
250  QTest::newRow("qlonglong-max, base 16")
251  << std::numeric_limits<qlonglong>::max() << 16 << (QChar(u'7') + QString(15, u'f'));
252  QTest::newRow("qlonglong-min, base 16") << std::numeric_limits<qlonglong>::min() << 16
253  << (QStringLiteral("-8") + QString(15, u'0'));
254 }
255 
256 void tst_QString::number_qulonglong_data()
257 {
258  QTest::addColumn<qulonglong>("number");
259  QTest::addColumn<int>("base");
260  QTest::addColumn<QString>("expected");
261 
262  number_integer_common<qulonglong>();
263 
264  QTest::newRow("qlonglong-max + 1")
265  << (qulonglong(std::numeric_limits<qlonglong>::max()) + 1) << 10
266  << QStringLiteral("9223372036854775808");
267  QTest::newRow("qulonglong-max")
268  << std::numeric_limits<qulonglong>::max() << 10
269  << QStringLiteral("18446744073709551615");
270  QTest::newRow("qulonglong-max, base 2")
271  << std::numeric_limits<qulonglong>::max() << 2 << QString(64, u'1');
272  QTest::newRow("qulonglong-max, base 16")
273  << std::numeric_limits<qulonglong>::max() << 16 << QString(16, u'f');
274 }
275 
276 void tst_QString::number_double_data()
277 {
278  QTest::addColumn<double>("number");
279  QTest::addColumn<char>("format");
280  QTest::addColumn<int>("precision");
281  QTest::addColumn<QString>("expected");
282 
283  struct
284  {
285  double d;
286  char f;
287  int p;
288  QString expected;
289  } data[] = {
290  { 0.0, 'f', 0, QStringLiteral("0") },
291  { 0.0001, 'f', 0, QStringLiteral("0") },
292  { 0.1234, 'f', 5, QStringLiteral("0.12340") },
293  { -0.1234, 'f', 5, QStringLiteral("-0.12340") },
294  { 0.5 + qSqrt(1.25), 'f', 15, QStringLiteral("1.618033988749895") },
295  { std::numeric_limits<double>::epsilon(), 'g', 10, QStringLiteral("2.220446049e-16") },
296  { 0.0001, 'E', 1, QStringLiteral("1.0E-04") },
297  { 1e8, 'E', 1, QStringLiteral("1.0E+08") },
298  { -1e8, 'E', 1, QStringLiteral("-1.0E+08") },
299  };
300 
301  for (auto &datum : data) {
302  QTest::addRow("%s, format '%c', precision %d", qPrintable(datum.expected), datum.f,
303  datum.p)
304  << datum.d << datum.f << datum.p << datum.expected;
305  }
306 }
307 
308 void tst_QString::number_double()
309 {
310  QFETCH(double, number);
311  QFETCH(char, format);
312  QFETCH(int, precision);
313  QFETCH(QString, expected);
314 
315  QString actual;
316  QBENCHMARK {
317  actual = QString::number(number, format, precision);
318  }
319  QCOMPARE(actual, expected);
320 }
321 
323 
324 #include "tst_bench_qstring.moc"
small capitals from c petite p scientific f u
Definition: afcover.h:88
small capitals from c petite p scientific i
[1]
Definition: afcover.h:80
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:84
static constexpr char16_t highSurrogate(char32_t ucs4) noexcept
Definition: qchar.h:549
static constexpr char16_t lowSurrogate(char32_t ucs4) noexcept
Definition: qchar.h:553
The QObject class is the base class of all Qt objects.
Definition: qobject.h:125
The QRegularExpression class provides pattern matching using regular expressions.
The QString class provides a Unicode character string.
Definition: qstring.h:388
QString section(QChar sep, qsizetype start, qsizetype end=-1, SectionFlags flags=SectionDefault) const
Definition: qstring.h:1272
static QString number(int, int base=10)
Definition: qstring.cpp:7538
Definition: base.h:37
float rx
QCOMPARE(spy.count(), 1)
Q_TESTLIB_EXPORT QTestData & newRow(const char *dataTag)
Definition: qtestcase.cpp:2658
Q_TESTLIB_EXPORT QTestData & addRow(const char *format,...) Q_ATTRIBUTE_FORMAT_PRINTF(1
Definition: qtestcase.cpp:2690
#define QString()
Definition: parse-defines.h:51
#define QBENCHMARK
Definition: qbenchmark.h:76
quint64 qulonglong
Definition: qglobal.h:302
auto qSqrt(T v)
Definition: qmath.h:132
GLboolean r
[2]
GLfloat GLfloat f
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLint GLsizei GLsizei GLenum format
GLuint64EXT * result
[6]
Definition: qopenglext.h:10932
GLdouble s
[6]
Definition: qopenglext.h:235
GLfloat GLfloat p
[1]
Definition: qopenglext.h:12698
GLubyte * pattern
Definition: qopenglext.h:2744
GLenum GLint GLint * precision
Definition: qopenglext.h:1890
#define QStringLiteral(str)
#define QTEST_APPLESS_MAIN(TestObject)
Definition: qtest.h:632
#define QFETCH(Type, name)
Definition: qtestcase.h:230
#define Q_OBJECT
Definition: qtmetamacros.h:158
#define slots
Definition: qtmetamacros.h:76
Q_UNUSED(salary)
[21]
void number_integer_common()
QString escape(const QString &s)
QString escape< QString >(const QString &s)
void optimize(RX &)
const qreal epsilon
Definition: tst_qline.cpp:63