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
52QT_BEGIN_NAMESPACE
53
54class QRegExp;
55class QRegularExpression;
56
57#if !defined(QT_NO_JAVA_STYLE_ITERATORS)
58typedef QListIterator<QString> QStringListIterator;
59typedef QMutableListIterator<QString> QMutableStringListIterator;
60#endif
61
62class QStringList;
63
64#ifdef Q_QDOC
65class QStringList : public QList<QString>
66#else
67template <> struct QListSpecialMethods<QString>
68#endif
69{
70#ifndef Q_QDOC
71protected:
72 ~QListSpecialMethods() = default;
73#endif
74public:
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
105private:
106 inline QStringList *self();
107 inline const QStringList *self() const;
108};
109
110// ### Qt6: check if there's a better way
111class QStringList : public QList<QString>
112{
113#endif
114public:
115 inline QStringList() noexcept { }
116 inline explicit QStringList(const QString &i) { append(i); }
117 inline QStringList(const QList<QString> &l) : QList<QString>(l) { }
118 inline QStringList(QList<QString> &&l) noexcept : QList<QString>(std::move(l)) { }
119 inline QStringList(std::initializer_list<QString> args) : QList<QString>(args) { }
120 template <typename InputIterator, QtPrivate::IfIsInputIterator<InputIterator> = true>
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
166Q_DECLARE_TYPEINFO(QStringList, Q_MOVABLE_TYPE);
167
168#ifndef Q_QDOC
169inline QStringList *QListSpecialMethods<QString>::self()
170{ return static_cast<QStringList *>(this); }
171inline const QStringList *QListSpecialMethods<QString>::self() const
172{ return static_cast<const QStringList *>(this); }
173
174namespace 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
216inline void QListSpecialMethods<QString>::sort(Qt::CaseSensitivity cs)
217{
218 QtPrivate::QStringList_sort(self(), cs);
219}
220
221inline int QListSpecialMethods<QString>::removeDuplicates()
222{
223 return QtPrivate::QStringList_removeDuplicates(self());
224}
225
226#if QT_STRINGVIEW_LEVEL < 2
227inline QString QListSpecialMethods<QString>::join(const QString &sep) const
228{
229 return QtPrivate::QStringList_join(self(), sep.constData(), sep.length());
230}
231#endif
232
233inline QString QListSpecialMethods<QString>::join(QStringView sep) const
234{
235 return QtPrivate::QStringList_join(self(), sep);
236}
237
238QString QListSpecialMethods<QString>::join(QLatin1String sep) const
239{
240 return QtPrivate::QStringList_join(*self(), sep);
241}
242
243inline QString QListSpecialMethods<QString>::join(QChar sep) const
244{
245 return QtPrivate::QStringList_join(self(), &sep, 1);
246}
247
248inline 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
254inline 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
261inline bool QStringList::contains(const QString &str, Qt::CaseSensitivity cs) const
262{
263 return QtPrivate::QStringList_contains(this, str, cs);
264}
265#endif
266
267inline bool QStringList::contains(QLatin1String str, Qt::CaseSensitivity cs) const
268{
269 return QtPrivate::QStringList_contains(this, str, cs);
270}
271
272inline bool QStringList::contains(QStringView str, Qt::CaseSensitivity cs) const
273{
274 return QtPrivate::QStringList_contains(this, str, cs);
275}
276
277inline 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
284inline 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
290inline 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
296inline 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
303inline QStringList operator+(const QList<QString> &one, const QStringList &other)
304{
305 QStringList n = one;
306 n += other;
307 return n;
308}
309
310inline int QStringList::indexOf(QStringView string, int from) const
311{
312 return QtPrivate::indexOf<QString, QStringView>(*this, string, from);
313}
314
315inline int QStringList::indexOf(QLatin1String string, int from) const
316{
317 return QtPrivate::indexOf<QString, QLatin1String>(*this, string, from);
318}
319
320inline int QStringList::lastIndexOf(QStringView string, int from) const
321{
322 return QtPrivate::lastIndexOf<QString, QStringView>(*this, string, from);
323}
324
325inline 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
331inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QRegExp &rx, const QString &after)
332{
333 QtPrivate::QStringList_replaceInStrings(self(), rx, after);
334 return *self();
335}
336
337inline QStringList QListSpecialMethods<QString>::filter(const QRegExp &rx) const
338{
339 return QtPrivate::QStringList_filter(self(), rx);
340}
341
342inline int QStringList::indexOf(const QRegExp &rx, int from) const
343{
344 return QtPrivate::QStringList_indexOf(this, rx, from);
345}
346
347inline int QStringList::lastIndexOf(const QRegExp &rx, int from) const
348{
349 return QtPrivate::QStringList_lastIndexOf(this, rx, from);
350}
351
352inline int QStringList::indexOf(QRegExp &rx, int from) const
353{
354 return QtPrivate::QStringList_indexOf(this, rx, from);
355}
356
357inline 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)
364inline QStringList &QListSpecialMethods<QString>::replaceInStrings(const QRegularExpression &rx, const QString &after)
365{
366 QtPrivate::QStringList_replaceInStrings(self(), rx, after);
367 return *self();
368}
369
370inline QStringList QListSpecialMethods<QString>::filter(const QRegularExpression &rx) const
371{
372 return QtPrivate::QStringList_filter(self(), rx);
373}
374
375inline int QStringList::indexOf(const QRegularExpression &rx, int from) const
376{
377 return QtPrivate::QStringList_indexOf(this, rx, from);
378}
379
380inline 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
388inline
389QList<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
400inline
401QList<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
412QT_END_NAMESPACE
413
414#endif // QSTRINGLIST_H
415