1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Copyright (C) 2016 Intel Corporation.
5 ** Contact: https://www.qt.io/licensing/
6 **
7 ** This file is part of the QtCore module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** Commercial License Usage
11 ** Licensees holding valid commercial Qt licenses may use this file in
12 ** accordance with the commercial license agreement provided with the
13 ** Software or, alternatively, in accordance with the terms contained in
14 ** a written agreement between you and The Qt Company. For licensing terms
15 ** and conditions see https://www.qt.io/terms-conditions. For further
16 ** information use the contact form at https://www.qt.io/contact-us.
17 **
18 ** GNU Lesser General Public License Usage
19 ** Alternatively, this file may be used under the terms of the GNU Lesser
20 ** General Public License version 3 as published by the Free Software
21 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
22 ** packaging of this file. Please review the following information to
23 ** ensure the GNU Lesser General Public License version 3 requirements
24 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
25 **
26 ** GNU General Public License Usage
27 ** Alternatively, this file may be used under the terms of the GNU
28 ** General Public License version 2.0 or (at your option) the GNU General
29 ** Public license version 3 or any later version approved by the KDE Free
30 ** Qt Foundation. The licenses are as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
32 ** included in the packaging of this file. Please review the following
33 ** information to ensure the GNU General Public License requirements will
34 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
35 ** https://www.gnu.org/licenses/gpl-3.0.html.
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 #include <QtCore/qlist.h>
42
43 #ifndef QSTRINGLIST_H
44 #define QSTRINGLIST_H
45
46 #include <QtCore/qalgorithms.h>
47 #include <QtCore/qcontainertools_impl.h>
48 #include <QtCore/qregexp.h>
49 #include <QtCore/qstring.h>
50 #include <QtCore/qstringmatcher.h>
51
52 QT_BEGIN_NAMESPACE
53
54 class QRegExp;
55 class QRegularExpression;
56
57 #if !defined(QT_NO_JAVA_STYLE_ITERATORS)
58 typedef QListIterator<QString> QStringListIterator;
59 typedef QMutableListIterator<QString> QMutableStringListIterator;
60 #endif
61
62 class QStringList;
63
64 #ifdef Q_QDOC
65 class QStringList : public QList<QString>
66 #else
67 template <> struct QListSpecialMethods<QString>
68 #endif
69 {
70 #ifndef Q_QDOC
71 protected:
72 ~QListSpecialMethods() = default;
73 #endif
74 public:
75 inline void sort(Qt::CaseSensitivity cs = Qt::CaseSensitive);
76 inline int removeDuplicates();
77
78 #if QT_STRINGVIEW_LEVEL < 2
79 inline QString join(const QString &sep) const;
80 #endif
81 inline QString join(QStringView sep) const;
82 inline QString join(QLatin1String sep) const;
83 inline QString join(QChar sep) const;
84
85 inline QStringList filter(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
86 inline QStringList &replaceInStrings(QStringView before, QStringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
87 #if QT_STRINGVIEW_LEVEL < 2
88 inline QStringList filter(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
89 inline QStringList &replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
90 inline QStringList &replaceInStrings(const QString &before, QStringView after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
91 inline QStringList &replaceInStrings(QStringView before, const QString &after, Qt::CaseSensitivity cs = Qt::CaseSensitive);
92 #endif
93
94 #ifndef QT_NO_REGEXP
95 inline QStringList filter(const QRegExp &rx) const;
96 inline QStringList &replaceInStrings(const QRegExp &rx, const QString &after);
97 #endif
98
99 #if QT_CONFIG(regularexpression)
100 inline QStringList filter(const QRegularExpression &re) const;
101 inline QStringList &replaceInStrings(const QRegularExpression &re, const QString &after);
102 #endif // QT_CONFIG(regularexpression)
103
104 #ifndef Q_QDOC
105 private:
106 inline QStringList *self();
107 inline const QStringList *self() const;
108 };
109
110 // ### Qt6: check if there's a better way
111 class QStringList : public QList<QString>
112 {
113 #endif
114 public:
QStringList()115 inline QStringList() noexcept { }
QStringList(const QString & i)116 inline explicit QStringList(const QString &i) { append(i); }
QStringList(const QList<QString> & l)117 inline QStringList(const QList<QString> &l) : QList<QString>(l) { }
QStringList(QList<QString> && l)118 inline QStringList(QList<QString> &&l) noexcept : QList<QString>(std::move(l)) { }
QStringList(std::initializer_list<QString> args)119 inline QStringList(std::initializer_list<QString> args) : QList<QString>(args) { }
120 template <typename InputIterator, QtPrivate::IfIsInputIterator<InputIterator> = true>
QStringList(InputIterator first,InputIterator last)121 inline QStringList(InputIterator first, InputIterator last)
122 : QList<QString>(first, last) { }
123
124 QStringList &operator=(const QList<QString> &other)
125 { QList<QString>::operator=(other); return *this; }
126 QStringList &operator=(QList<QString> &&other) noexcept
127 { QList<QString>::operator=(std::move(other)); return *this; }
128
129 #if QT_STRINGVIEW_LEVEL < 2
130 inline bool contains(const QString &str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
131 #endif
132 inline bool contains(QLatin1String str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
133 inline bool contains(QStringView str, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;
134
135 inline QStringList operator+(const QStringList &other) const
136 { QStringList n = *this; n += other; return n; }
137 inline QStringList &operator<<(const QString &str)
138 { append(str); return *this; }
139 inline QStringList &operator<<(const QStringList &l)
140 { *this += l; return *this; }
141 inline QStringList &operator<<(const QList<QString> &l)
142 { *this += l; return *this; }
143
144 inline int indexOf(QStringView str, int from = 0) const;
145 inline int indexOf(QLatin1String str, int from = 0) const;
146
147 inline int lastIndexOf(QStringView str, int from = -1) const;
148 inline int lastIndexOf(QLatin1String str, int from = -1) const;
149
150 #ifndef QT_NO_REGEXP
151 inline int indexOf(const QRegExp &rx, int from = 0) const;
152 inline int lastIndexOf(const QRegExp &rx, int from = -1) const;
153 inline int indexOf(QRegExp &rx, int from = 0) const;
154 inline int lastIndexOf(QRegExp &rx, int from = -1) const;
155 #endif
156
157 #if QT_CONFIG(regularexpression)
158 inline int indexOf(const QRegularExpression &re, int from = 0) const;
159 inline int lastIndexOf(const QRegularExpression &re, int from = -1) const;
160 #endif // QT_CONFIG(regularexpression)
161
162 using QList<QString>::indexOf;
163 using QList<QString>::lastIndexOf;
164 };
165
166 Q_DECLARE_TYPEINFO(QStringList, Q_MOVABLE_TYPE);
167
168 #ifndef Q_QDOC
self()169 inline QStringList *QListSpecialMethods<QString>::self()
170 { return static_cast<QStringList *>(this); }
self()171 inline const QStringList *QListSpecialMethods<QString>::self() const
172 { return static_cast<const QStringList *>(this); }
173
174 namespace QtPrivate {
175 void Q_CORE_EXPORT QStringList_sort(QStringList *that, Qt::CaseSensitivity cs);
176 int Q_CORE_EXPORT QStringList_removeDuplicates(QStringList *that);
177 QString Q_CORE_EXPORT QStringList_join(const QStringList *that, QStringView sep);
178 QString Q_CORE_EXPORT QStringList_join(const QStringList *that, const QChar *sep, int seplen);
179 Q_CORE_EXPORT QString QStringList_join(const QStringList &list, QLatin1String sep);
180 QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, QStringView str,
181 Qt::CaseSensitivity cs);
182 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
183 QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QString &str,
184 Qt::CaseSensitivity cs);
185 #endif
186
187 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
188 bool Q_CORE_EXPORT QStringList_contains(const QStringList *that, const QString &str, Qt::CaseSensitivity cs);
189 #endif
190 bool Q_CORE_EXPORT QStringList_contains(const QStringList *that, QStringView str, Qt::CaseSensitivity cs);
191 bool Q_CORE_EXPORT QStringList_contains(const QStringList *that, QLatin1String str, Qt::CaseSensitivity cs);
192 void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, QStringView before, QStringView after,
193 Qt::CaseSensitivity cs);
194 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
195 void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, const QString &before, const QString &after,
196 Qt::CaseSensitivity cs);
197 #endif
198
199 #ifndef QT_NO_REGEXP
200 void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, const QRegExp &rx, const QString &after);
201 QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QRegExp &re);
202 int Q_CORE_EXPORT QStringList_indexOf(const QStringList *that, const QRegExp &rx, int from);
203 int Q_CORE_EXPORT QStringList_lastIndexOf(const QStringList *that, const QRegExp &rx, int from);
204 int Q_CORE_EXPORT QStringList_indexOf(const QStringList *that, QRegExp &rx, int from);
205 int Q_CORE_EXPORT QStringList_lastIndexOf(const QStringList *that, QRegExp &rx, int from);
206 #endif
207
208 #if QT_CONFIG(regularexpression)
209 void Q_CORE_EXPORT QStringList_replaceInStrings(QStringList *that, const QRegularExpression &rx, const QString &after);
210 QStringList Q_CORE_EXPORT QStringList_filter(const QStringList *that, const QRegularExpression &re);
211 int Q_CORE_EXPORT QStringList_indexOf(const QStringList *that, const QRegularExpression &re, int from);
212 int Q_CORE_EXPORT QStringList_lastIndexOf(const QStringList *that, const QRegularExpression &re, int from);
213 #endif // QT_CONFIG(regularexpression)
214 }
215
sort(Qt::CaseSensitivity cs)216 inline void QListSpecialMethods<QString>::sort(Qt::CaseSensitivity cs)
217 {
218 QtPrivate::QStringList_sort(self(), cs);
219 }
220
removeDuplicates()221 inline int QListSpecialMethods<QString>::removeDuplicates()
222 {
223 return QtPrivate::QStringList_removeDuplicates(self());
224 }
225
226 #if QT_STRINGVIEW_LEVEL < 2
join(const QString & sep)227 inline QString QListSpecialMethods<QString>::join(const QString &sep) const
228 {
229 return QtPrivate::QStringList_join(self(), sep.constData(), sep.length());
230 }
231 #endif
232
join(QStringView sep)233 inline QString QListSpecialMethods<QString>::join(QStringView sep) const
234 {
235 return QtPrivate::QStringList_join(self(), sep);
236 }
237
join(QLatin1String sep)238 QString QListSpecialMethods<QString>::join(QLatin1String sep) const
239 {
240 return QtPrivate::QStringList_join(*self(), sep);
241 }
242
join(QChar sep)243 inline QString QListSpecialMethods<QString>::join(QChar sep) const
244 {
245 return QtPrivate::QStringList_join(self(), &sep, 1);
246 }
247
filter(QStringView str,Qt::CaseSensitivity cs)248 inline QStringList QListSpecialMethods<QString>::filter(QStringView str, Qt::CaseSensitivity cs) const
249 {
250 return QtPrivate::QStringList_filter(self(), str, cs);
251 }
252
253 #if QT_STRINGVIEW_LEVEL < 2
filter(const QString & str,Qt::CaseSensitivity cs)254 inline QStringList QListSpecialMethods<QString>::filter(const QString &str, Qt::CaseSensitivity cs) const
255 {
256 return QtPrivate::QStringList_filter(self(), str, cs);
257 }
258 #endif
259
260 #if QT_STRINGVIEW_LEVEL < 2
contains(const QString & str,Qt::CaseSensitivity cs)261 inline bool QStringList::contains(const QString &str, Qt::CaseSensitivity cs) const
262 {
263 return QtPrivate::QStringList_contains(this, str, cs);
264 }
265 #endif
266
contains(QLatin1String str,Qt::CaseSensitivity cs)267 inline bool QStringList::contains(QLatin1String str, Qt::CaseSensitivity cs) const
268 {
269 return QtPrivate::QStringList_contains(this, str, cs);
270 }
271
contains(QStringView str,Qt::CaseSensitivity cs)272 inline bool QStringList::contains(QStringView str, Qt::CaseSensitivity cs) const
273 {
274 return QtPrivate::QStringList_contains(this, str, cs);
275 }
276
replaceInStrings(QStringView before,QStringView after,Qt::CaseSensitivity cs)277 inline QStringList &QListSpecialMethods<QString>::replaceInStrings(QStringView before, QStringView after, Qt::CaseSensitivity cs)
278 {
279 QtPrivate::QStringList_replaceInStrings(self(), before, after, cs);
280 return *self();
281 }
282
283 #if QT_STRINGVIEW_LEVEL < 2
replaceInStrings(const QString & before,const QString & after,Qt::CaseSensitivity cs)284 inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
285 {
286 QtPrivate::QStringList_replaceInStrings(self(), before, after, cs);
287 return *self();
288 }
289
replaceInStrings(QStringView before,const QString & after,Qt::CaseSensitivity cs)290 inline QStringList &QListSpecialMethods<QString>::replaceInStrings(QStringView before, const QString &after, Qt::CaseSensitivity cs)
291 {
292 QtPrivate::QStringList_replaceInStrings(self(), before, qToStringViewIgnoringNull(after), cs);
293 return *self();
294 }
295
replaceInStrings(const QString & before,QStringView after,Qt::CaseSensitivity cs)296 inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QString &before, QStringView after, Qt::CaseSensitivity cs)
297 {
298 QtPrivate::QStringList_replaceInStrings(self(), QStringView(before), after, cs);
299 return *self();
300 }
301 #endif
302
303 inline QStringList operator+(const QList<QString> &one, const QStringList &other)
304 {
305 QStringList n = one;
306 n += other;
307 return n;
308 }
309
indexOf(QStringView string,int from)310 inline int QStringList::indexOf(QStringView string, int from) const
311 {
312 return QtPrivate::indexOf<QString, QStringView>(*this, string, from);
313 }
314
indexOf(QLatin1String string,int from)315 inline int QStringList::indexOf(QLatin1String string, int from) const
316 {
317 return QtPrivate::indexOf<QString, QLatin1String>(*this, string, from);
318 }
319
lastIndexOf(QStringView string,int from)320 inline int QStringList::lastIndexOf(QStringView string, int from) const
321 {
322 return QtPrivate::lastIndexOf<QString, QStringView>(*this, string, from);
323 }
324
lastIndexOf(QLatin1String string,int from)325 inline int QStringList::lastIndexOf(QLatin1String string, int from) const
326 {
327 return QtPrivate::lastIndexOf<QString, QLatin1String>(*this, string, from);
328 }
329
330 #ifndef QT_NO_REGEXP
replaceInStrings(const QRegExp & rx,const QString & after)331 inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QRegExp &rx, const QString &after)
332 {
333 QtPrivate::QStringList_replaceInStrings(self(), rx, after);
334 return *self();
335 }
336
filter(const QRegExp & rx)337 inline QStringList QListSpecialMethods<QString>::filter(const QRegExp &rx) const
338 {
339 return QtPrivate::QStringList_filter(self(), rx);
340 }
341
indexOf(const QRegExp & rx,int from)342 inline int QStringList::indexOf(const QRegExp &rx, int from) const
343 {
344 return QtPrivate::QStringList_indexOf(this, rx, from);
345 }
346
lastIndexOf(const QRegExp & rx,int from)347 inline int QStringList::lastIndexOf(const QRegExp &rx, int from) const
348 {
349 return QtPrivate::QStringList_lastIndexOf(this, rx, from);
350 }
351
indexOf(QRegExp & rx,int from)352 inline int QStringList::indexOf(QRegExp &rx, int from) const
353 {
354 return QtPrivate::QStringList_indexOf(this, rx, from);
355 }
356
lastIndexOf(QRegExp & rx,int from)357 inline int QStringList::lastIndexOf(QRegExp &rx, int from) const
358 {
359 return QtPrivate::QStringList_lastIndexOf(this, rx, from);
360 }
361 #endif
362
363 #if QT_CONFIG(regularexpression)
replaceInStrings(const QRegularExpression & rx,const QString & after)364 inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QRegularExpression &rx, const QString &after)
365 {
366 QtPrivate::QStringList_replaceInStrings(self(), rx, after);
367 return *self();
368 }
369
filter(const QRegularExpression & rx)370 inline QStringList QListSpecialMethods<QString>::filter(const QRegularExpression &rx) const
371 {
372 return QtPrivate::QStringList_filter(self(), rx);
373 }
374
indexOf(const QRegularExpression & rx,int from)375 inline int QStringList::indexOf(const QRegularExpression &rx, int from) const
376 {
377 return QtPrivate::QStringList_indexOf(this, rx, from);
378 }
379
lastIndexOf(const QRegularExpression & rx,int from)380 inline int QStringList::lastIndexOf(const QRegularExpression &rx, int from) const
381 {
382 return QtPrivate::QStringList_lastIndexOf(this, rx, from);
383 }
384 #endif // QT_CONFIG(regularexpression)
385 #endif // Q_QDOC
386
387 // those methods need to be here, so they can be implemented inline
388 inline
split(QStringView sep,Qt::SplitBehavior behavior,Qt::CaseSensitivity cs)389 QList<QStringView> QStringView::split(QStringView sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const
390 {
391 Q_ASSERT(int(m_size) == m_size);
392 QString s = QString::fromRawData(data(), int(m_size));
393 const auto split = s.splitRef(sep.toString(), behavior, cs);
394 QList<QStringView> result;
395 for (const QStringRef &r : split)
396 result.append(QStringView(m_data + r.position(), r.size()));
397 return result;
398 }
399
400 inline
split(QChar sep,Qt::SplitBehavior behavior,Qt::CaseSensitivity cs)401 QList<QStringView> QStringView::split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const
402 {
403 Q_ASSERT(int(m_size) == m_size);
404 QString s = QString::fromRawData(data(), int(m_size));
405 const auto split = s.splitRef(sep, behavior, cs);
406 QList<QStringView> result;
407 for (const QStringRef &r : split)
408 result.append(QStringView(m_data + r.position(), r.size()));
409 return result;
410 }
411
412 QT_END_NAMESPACE
413
414 #endif // QSTRINGLIST_H
415