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