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 QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
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 Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include <qstringlist.h>
41#include <qregexp.h>
42#include <qset.h>
43#if QT_CONFIG(regularexpression)
44# include <qregularexpression.h>
45#endif
46#include <private/qduplicatetracker_p.h>
47
48#include <algorithm>
49QT_BEGIN_NAMESPACE
50
51/*! \typedef QStringListIterator
52 \relates QStringList
53
54 The QStringListIterator type definition provides a Java-style const
55 iterator for QStringList.
56
57 QStringList provides both \l{Java-style iterators} and
58 \l{STL-style iterators}. The Java-style const iterator is simply
59 a type definition for QListIterator<QString>.
60
61 \sa QMutableStringListIterator, QStringList::const_iterator
62*/
63
64/*! \typedef QMutableStringListIterator
65 \relates QStringList
66
67 The QStringListIterator type definition provides a Java-style
68 non-const iterator for QStringList.
69
70 QStringList provides both \l{Java-style iterators} and
71 \l{STL-style iterators}. The Java-style non-const iterator is
72 simply a type definition for QMutableListIterator<QString>.
73
74 \sa QStringListIterator, QStringList::iterator
75*/
76
77/*!
78 \class QStringList
79 \inmodule QtCore
80 \brief The QStringList class provides a list of strings.
81
82 \ingroup tools
83 \ingroup shared
84 \ingroup string-processing
85
86 \reentrant
87
88 QStringList inherits from QList<QString>. Like QList, QStringList is
89 \l{implicitly shared}. It provides fast index-based access as well as fast
90 insertions and removals. Passing string lists as value parameters is both
91 fast and safe.
92
93 All of QList's functionality also applies to QStringList. For example, you
94 can use isEmpty() to test whether the list is empty, and you can call
95 functions like append(), prepend(), insert(), replace(), removeAll(),
96 removeAt(), removeFirst(), removeLast(), and removeOne() to modify a
97 QStringList. In addition, QStringList provides a few convenience
98 functions that make handling lists of strings easier:
99
100 \tableofcontents
101
102 \section1 Initializing
103
104 The default constructor creates an empty list. You can use the
105 initializer-list constructor to create a list with elements:
106
107 \snippet qstringlist/main.cpp 0a
108
109 \section1 Adding Strings
110
111 Strings can be added to a list using the \l
112 {QList::insert()}{insert()} \l
113 {QList::append()}{append()}, \l
114 {QList::operator+=()}{operator+=()} and \l
115 {operator<<()} functions.
116
117 \l{operator<<()} can be used to
118 conveniently add multiple elements to a list:
119
120 \snippet qstringlist/main.cpp 0b
121
122 \section1 Iterating Over the Strings
123
124 To iterate over a list, you can either use index positions or
125 QList's Java-style and STL-style iterator types:
126
127 Indexing:
128
129 \snippet qstringlist/main.cpp 1
130
131 Java-style iterator:
132
133 \snippet qstringlist/main.cpp 2
134
135 STL-style iterator:
136
137 \snippet qstringlist/main.cpp 3
138
139 The QStringListIterator class is simply a type definition for
140 QListIterator<QString>. QStringList also provide the
141 QMutableStringListIterator class which is a type definition for
142 QMutableListIterator<QString>.
143
144 \section1 Manipulating the Strings
145
146 QStringList provides several functions allowing you to manipulate
147 the contents of a list. You can concatenate all the strings in a
148 string list into a single string (with an optional separator)
149 using the join() function. For example:
150
151 \snippet qstringlist/main.cpp 4
152
153 The argument to join can be a single character or a string.
154
155 To break up a string into a string list, use the QString::split()
156 function:
157
158 \snippet qstringlist/main.cpp 6
159
160 The argument to split can be a single character, a string, a
161 QRegularExpression or a (deprecated) QRegExp.
162
163 In addition, the \l {QStringList::operator+()}{operator+()}
164 function allows you to concatenate two string lists into one. To
165 sort a string list, use the sort() function.
166
167 QString list also provides the filter() function which lets you
168 to extract a new list which contains only those strings which
169 contain a particular substring (or match a particular regular
170 expression):
171
172 \snippet qstringlist/main.cpp 7
173
174 The contains() function tells you whether the list contains a
175 given string, while the indexOf() function returns the index of
176 the first occurrence of the given string. The lastIndexOf()
177 function on the other hand, returns the index of the last
178 occurrence of the string.
179
180 Finally, the replaceInStrings() function calls QString::replace()
181 on each string in the string list in turn. For example:
182
183 \snippet qstringlist/main.cpp 8
184
185 \sa QString
186*/
187
188/*!
189 \fn QStringList::QStringList()
190
191 Constructs an empty string list.
192*/
193
194/*!
195 \fn QStringList::QStringList(const QString &str)
196
197 Constructs a string list that contains the given string, \a
198 str. Longer lists are easily created like this:
199
200 \snippet qstringlist/main.cpp 9
201
202 \sa append()
203*/
204
205/*!
206 \fn QStringList::QStringList(const QList<QString> &other)
207
208 Constructs a copy of \a other.
209
210 This operation takes \l{constant time}, because QStringList is
211 \l{implicitly shared}. This makes returning a QStringList from a
212 function very fast. If a shared instance is modified, it will be
213 copied (copy-on-write), and that takes \l{linear time}.
214
215 \sa operator=()
216*/
217
218/*!
219 \fn QStringList::QStringList(QList<QString> &&other)
220 \overload
221 \since 5.4
222
223 Move-constructs from QList<QString>.
224
225 After a successful construction, \a other will be empty.
226*/
227
228/*!
229 \fn QStringList &QStringList::operator=(const QList<QString> &other)
230 \since 5.4
231
232 Copy assignment operator from QList<QString>. Assigns the \a other
233 list of strings to this string list.
234
235 After the operation, \a other and \c *this will be equal.
236*/
237
238/*!
239 \fn QStringList &QStringList::operator=(QList<QString> &&other)
240 \overload
241 \since 5.4
242
243 Move assignment operator from QList<QString>. Moves the \a other
244 list of strings to this string list.
245
246 After the operation, \a other will be empty.
247*/
248
249/*!
250 \fn void QStringList::sort(Qt::CaseSensitivity cs)
251
252 Sorts the list of strings in ascending order.
253 If \a cs is \l Qt::CaseSensitive (the default), the string comparison
254 is case sensitive; otherwise the comparison is case insensitive.
255
256 Sorting is performed using the STL's std::sort() algorithm,
257 which averages \l{linear-logarithmic time}, i.e. O(\e{n} log \e{n}).
258
259 If you want to sort your strings in an arbitrary order, consider
260 using the QMap class. For example, you could use a QMap<QString,
261 QString> to create a case-insensitive ordering (e.g. with the keys
262 being lower-case versions of the strings, and the values being the
263 strings), or a QMap<int, QString> to sort the strings by some
264 integer index.
265*/
266
267namespace {
268struct CaseInsensitiveLessThan {
269 typedef bool result_type;
270 result_type operator()(const QString &s1, const QString &s2) const
271 {
272 return s1.compare(s: s2, cs: Qt::CaseInsensitive) < 0;
273 }
274};
275}
276
277void QtPrivate::QStringList_sort(QStringList *that, Qt::CaseSensitivity cs)
278{
279 if (cs == Qt::CaseSensitive)
280 std::sort(first: that->begin(), last: that->end());
281 else
282 std::sort(first: that->begin(), last: that->end(), comp: CaseInsensitiveLessThan());
283}
284
285
286#if QT_STRINGVIEW_LEVEL < 2
287/*!
288 \fn QStringList QStringList::filter(const QString &str, Qt::CaseSensitivity cs) const
289
290 Returns a list of all the strings containing the substring \a str.
291
292 If \a cs is \l Qt::CaseSensitive (the default), the string
293 comparison is case sensitive; otherwise the comparison is case
294 insensitive.
295
296 \snippet qstringlist/main.cpp 5
297 \snippet qstringlist/main.cpp 10
298
299 This is equivalent to
300
301 \snippet qstringlist/main.cpp 11
302 \snippet qstringlist/main.cpp 12
303
304 \sa contains()
305*/
306#endif
307
308/*!
309 \fn QStringList QStringList::filter(QStringView str, Qt::CaseSensitivity cs) const
310 \overload
311 \since 5.14
312*/
313QStringList QtPrivate::QStringList_filter(const QStringList *that, QStringView str,
314 Qt::CaseSensitivity cs)
315{
316 QStringMatcher matcher(str, cs);
317 QStringList res;
318 for (int i = 0; i < that->size(); ++i)
319 if (matcher.indexIn(str: that->at(i)) != -1)
320 res << that->at(i);
321 return res;
322}
323
324#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
325/// Not really needed anymore, but kept for binary compatibility
326QStringList QtPrivate::QStringList_filter(const QStringList *that, const QString &str,
327 Qt::CaseSensitivity cs)
328{
329 QStringMatcher matcher(str, cs);
330 QStringList res;
331 for (int i = 0; i < that->size(); ++i)
332 if (matcher.indexIn(str: that->at(i)) != -1)
333 res << that->at(i);
334 return res;
335}
336#endif
337
338template<typename T>
339static bool stringList_contains(const QStringList &stringList, const T &str, Qt::CaseSensitivity cs)
340{
341 for (const auto &string : stringList) {
342 if (string.size() == str.size() && string.compare(str, cs) == 0)
343 return true;
344 }
345 return false;
346}
347
348
349#if QT_STRINGVIEW_LEVEL < 2
350/*!
351 \fn bool QStringList::contains(const QString &str, Qt::CaseSensitivity cs) const
352
353 Returns \c true if the list contains the string \a str; otherwise
354 returns \c false. The search is case insensitive if \a cs is
355 Qt::CaseInsensitive; the search is case sensitive by default.
356
357 \sa indexOf(), lastIndexOf(), QString::contains()
358 */
359#endif
360
361#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
362/// Not really needed anymore, but kept for binary compatibility
363bool QtPrivate::QStringList_contains(const QStringList *that, const QString &str,
364 Qt::CaseSensitivity cs)
365{
366 return stringList_contains(stringList: *that, str, cs);
367}
368#endif
369
370/*!
371 \fn bool QStringList::contains(QStringView str, Qt::CaseSensitivity cs) const
372 \overload
373 \since 5.12
374
375 Returns \c true if the list contains the string \a str; otherwise
376 returns \c false. The search is case insensitive if \a cs is
377 Qt::CaseInsensitive; the search is case sensitive by default.
378 */
379bool QtPrivate::QStringList_contains(const QStringList *that, QStringView str,
380 Qt::CaseSensitivity cs)
381{
382 return stringList_contains(stringList: *that, str, cs);
383}
384
385/*!
386 \fn bool QStringList::contains(QLatin1String str, Qt::CaseSensitivity cs) const
387 \overload
388 \since 5.10
389
390 Returns \c true if the list contains the string \a str; otherwise
391 returns \c false. The search is case insensitive if \a cs is
392 Qt::CaseInsensitive; the search is case sensitive by default.
393
394 \sa indexOf(), lastIndexOf(), QString::contains()
395 */
396bool QtPrivate::QStringList_contains(const QStringList *that, QLatin1String str,
397 Qt::CaseSensitivity cs)
398{
399 return stringList_contains(stringList: *that, str, cs);
400}
401
402/*!
403 \fn bool QStringList::indexOf(QStringView str, int from) const
404 \overload
405 \since 5.13
406
407 Returns the index position of the first occurrence of \a str in
408 the list, searching forward from index position \a from. Returns
409 -1 if no item matched.
410
411 \sa lastIndexOf(), contains()
412 */
413
414/*!
415 \fn bool QStringList::indexOf(QLatin1String str, int from) const
416 \overload
417 \since 5.13
418
419 Returns the index position of the first occurrence of \a str in
420 the list, searching forward from index position \a from. Returns
421 -1 if no item matched.
422
423 \sa lastIndexOf(), contains()
424 */
425
426/*!
427 \fn bool QStringList::lastIndexOf(QStringView str, int from) const
428 \overload
429 \since 5.13
430
431 Returns the index position of the last occurrence of \a str in
432 the list, searching backward from index position \a from. If \a
433 from is -1 (the default), the search starts at the last item.
434 Returns -1 if no item matched.
435
436 \sa indexOf(), contains()
437 */
438
439/*!
440 \fn bool QStringList::lastIndexOf(QLatin1String str, int from) const
441 \overload
442 \since 5.13
443
444 Returns the index position of the last occurrence of \a str in
445 the list, searching backward from index position \a from. If \a
446 from is -1 (the default), the search starts at the last item.
447 Returns -1 if no item matched.
448
449 \sa indexOf(), contains()
450 */
451
452#ifndef QT_NO_REGEXP
453/*!
454 \fn QStringList QStringList::filter(const QRegExp &rx) const
455
456 \overload
457
458 Returns a list of all the strings that match the regular
459 expression \a rx.
460*/
461QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegExp &rx)
462{
463 QStringList res;
464 for (int i = 0; i < that->size(); ++i)
465 if (that->at(i).contains(rx))
466 res << that->at(i);
467 return res;
468}
469#endif
470
471#if QT_CONFIG(regularexpression)
472/*!
473 \fn QStringList QStringList::filter(const QRegularExpression &re) const
474 \overload
475 \since 5.0
476
477 Returns a list of all the strings that match the regular
478 expression \a re.
479*/
480QStringList QtPrivate::QStringList_filter(const QStringList *that, const QRegularExpression &re)
481{
482 QStringList res;
483 for (int i = 0; i < that->size(); ++i) {
484 if (that->at(i).contains(re))
485 res << that->at(i);
486 }
487 return res;
488}
489#endif // QT_CONFIG(regularexpression)
490
491#if QT_STRINGVIEW_LEVEL < 2
492/*!
493 \fn QStringList &QStringList::replaceInStrings(const QString &before, const QString &after, Qt::CaseSensitivity cs)
494
495 Returns a string list where every string has had the \a before
496 text replaced with the \a after text wherever the \a before text
497 is found. The \a before text is matched case-sensitively or not
498 depending on the \a cs flag.
499
500 For example:
501
502 \snippet qstringlist/main.cpp 5
503 \snippet qstringlist/main.cpp 13
504
505 \sa QString::replace()
506*/
507
508/*!
509 \fn QStringList &QStringList::replaceInStrings(QStringView before, const QString &after, Qt::CaseSensitivity cs)
510 \overload
511 \since 5.14
512*/
513
514/*!
515 \fn QStringList &QStringList::replaceInStrings(const QString &before, QStringView after, Qt::CaseSensitivity cs)
516 \overload
517 \since 5.14
518*/
519#endif
520
521/*!
522 \fn QStringList &QStringList::replaceInStrings(QStringView before, QStringView after, Qt::CaseSensitivity cs)
523 \overload
524 \since 5.14
525*/
526void QtPrivate::QStringList_replaceInStrings(QStringList *that, QStringView before,
527 QStringView after, Qt::CaseSensitivity cs)
528{
529 for (int i = 0; i < that->size(); ++i)
530 (*that)[i].replace(before: before.data(), blen: before.length(), after: after.data(), alen: after.length(), cs);
531}
532
533#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
534/// Not really needed anymore, but kept for binary compatibility
535void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QString &before,
536 const QString &after, Qt::CaseSensitivity cs)
537{
538 for (int i = 0; i < that->size(); ++i)
539 (*that)[i].replace(before, after, cs);
540}
541#endif
542
543
544#ifndef QT_NO_REGEXP
545/*!
546 \fn QStringList &QStringList::replaceInStrings(const QRegExp &rx, const QString &after)
547 \overload
548
549 Replaces every occurrence of the regexp \a rx, in each of the
550 string lists's strings, with \a after. Returns a reference to the
551 string list.
552
553 For example:
554
555 \snippet qstringlist/main.cpp 5
556 \snippet qstringlist/main.cpp 14
557
558 For regular expressions that contain \l{capturing parentheses},
559 occurrences of \b{\\1}, \b{\\2}, ..., in \a after are
560 replaced with \a{rx}.cap(1), \a{rx}.cap(2), ...
561
562 For example:
563
564 \snippet qstringlist/main.cpp 5
565 \snippet qstringlist/main.cpp 15
566*/
567void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegExp &rx, const QString &after)
568{
569 for (int i = 0; i < that->size(); ++i)
570 (*that)[i].replace(rx, after);
571}
572#endif
573
574#if QT_CONFIG(regularexpression)
575/*!
576 \fn QStringList &QStringList::replaceInStrings(const QRegularExpression &re, const QString &after)
577 \overload
578 \since 5.0
579
580 Replaces every occurrence of the regular expression \a re, in each of the
581 string lists's strings, with \a after. Returns a reference to the string
582 list.
583
584 For example:
585
586 \snippet qstringlist/main.cpp 5
587 \snippet qstringlist/main.cpp 16
588
589 For regular expressions that contain capturing groups,
590 occurrences of \b{\\1}, \b{\\2}, ..., in \a after are
591 replaced with the string captured by the corresponding capturing group.
592
593 For example:
594
595 \snippet qstringlist/main.cpp 5
596 \snippet qstringlist/main.cpp 17
597*/
598void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegularExpression &re, const QString &after)
599{
600 for (int i = 0; i < that->size(); ++i)
601 (*that)[i].replace(re, after);
602}
603#endif // QT_CONFIG(regularexpression)
604
605static int accumulatedSize(const QStringList &list, int seplen)
606{
607 int result = 0;
608 if (!list.isEmpty()) {
609 for (const auto &e : list)
610 result += e.size() + seplen;
611 result -= seplen;
612 }
613 return result;
614}
615
616#if QT_STRINGVIEW_LEVEL < 2
617/*!
618 \fn QString QStringList::join(const QString &separator) const
619
620 Joins all the string list's strings into a single string with each
621 element separated by the given \a separator (which can be an
622 empty string).
623
624 \sa QString::split()
625*/
626#endif
627
628/*!
629 \fn QString QStringList::join(QChar separator) const
630 \since 5.0
631 \overload join()
632*/
633QString QtPrivate::QStringList_join(const QStringList *that, const QChar *sep, int seplen)
634{
635 const int totalLength = accumulatedSize(list: *that, seplen);
636 const int size = that->size();
637
638 QString res;
639 if (totalLength == 0)
640 return res;
641 res.reserve(asize: totalLength);
642 for (int i = 0; i < size; ++i) {
643 if (i)
644 res.append(uc: sep, len: seplen);
645 res += that->at(i);
646 }
647 return res;
648}
649
650/*!
651 \fn QString QStringList::join(QLatin1String separator) const
652 \since 5.8
653 \overload join()
654*/
655QString QtPrivate::QStringList_join(const QStringList &list, QLatin1String sep)
656{
657 QString result;
658 if (!list.isEmpty()) {
659 result.reserve(asize: accumulatedSize(list, seplen: sep.size()));
660 const auto end = list.end();
661 auto it = list.begin();
662 result += *it;
663 while (++it != end) {
664 result += sep;
665 result += *it;
666 }
667 }
668 return result;
669}
670
671/*!
672 \fn QString QStringList::join(QStringView separator) const
673 \overload
674 \since 5.14
675*/
676QString QtPrivate::QStringList_join(const QStringList *that, QStringView sep)
677{
678 return QStringList_join(that, sep: sep.data(), seplen: sep.length());
679}
680
681/*!
682 \fn QStringList QStringList::operator+(const QStringList &other) const
683
684 Returns a string list that is the concatenation of this string
685 list with the \a other string list.
686
687 \sa append()
688*/
689
690/*!
691 \fn QStringList &QStringList::operator<<(const QString &str)
692
693 Appends the given string, \a str, to this string list and returns
694 a reference to the string list.
695
696 \sa append()
697*/
698
699/*!
700 \fn QStringList &QStringList::operator<<(const QStringList &other)
701
702 \overload
703
704 Appends the \a other string list to the string list and returns a reference to
705 the latter string list.
706*/
707
708/*!
709 \fn QStringList &QStringList::operator<<(const QList<QString> &other)
710 \since 5.4
711
712 \overload
713
714 Appends the \a other string list to the string list and returns a reference to
715 the latter string list.
716*/
717
718#ifndef QT_NO_REGEXP
719static int indexOfMutating(const QStringList *that, QRegExp &rx, int from)
720{
721 if (from < 0)
722 from = qMax(a: from + that->size(), b: 0);
723 for (int i = from; i < that->size(); ++i) {
724 if (rx.exactMatch(str: that->at(i)))
725 return i;
726 }
727 return -1;
728}
729
730static int lastIndexOfMutating(const QStringList *that, QRegExp &rx, int from)
731{
732 if (from < 0)
733 from += that->size();
734 else if (from >= that->size())
735 from = that->size() - 1;
736 for (int i = from; i >= 0; --i) {
737 if (rx.exactMatch(str: that->at(i)))
738 return i;
739 }
740 return -1;
741}
742
743/*!
744 \fn int QStringList::indexOf(const QRegExp &rx, int from) const
745
746 Returns the index position of the first exact match of \a rx in
747 the list, searching forward from index position \a from. Returns
748 -1 if no item matched.
749
750 \sa lastIndexOf(), contains(), QRegExp::exactMatch()
751*/
752int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegExp &rx, int from)
753{
754 QRegExp rx2(rx);
755 return indexOfMutating(that, rx&: rx2, from);
756}
757
758/*!
759 \fn int QStringList::indexOf(QRegExp &rx, int from) const
760 \overload indexOf()
761 \since 4.5
762
763 Returns the index position of the first exact match of \a rx in
764 the list, searching forward from index position \a from. Returns
765 -1 if no item matched.
766
767 If an item matched, the \a rx regular expression will contain the
768 matched objects (see QRegExp::matchedLength, QRegExp::cap).
769
770 \sa lastIndexOf(), contains(), QRegExp::exactMatch()
771*/
772int QtPrivate::QStringList_indexOf(const QStringList *that, QRegExp &rx, int from)
773{
774 return indexOfMutating(that, rx, from);
775}
776
777/*!
778 \fn int QStringList::lastIndexOf(const QRegExp &rx, int from) const
779
780 Returns the index position of the last exact match of \a rx in
781 the list, searching backward from index position \a from. If \a
782 from is -1 (the default), the search starts at the last item.
783 Returns -1 if no item matched.
784
785 \sa indexOf(), contains(), QRegExp::exactMatch()
786*/
787int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegExp &rx, int from)
788{
789 QRegExp rx2(rx);
790 return lastIndexOfMutating(that, rx&: rx2, from);
791}
792
793/*!
794 \fn int QStringList::lastIndexOf(QRegExp &rx, int from) const
795 \overload lastIndexOf()
796 \since 4.5
797
798 Returns the index position of the last exact match of \a rx in
799 the list, searching backward from index position \a from. If \a
800 from is -1 (the default), the search starts at the last item.
801 Returns -1 if no item matched.
802
803 If an item matched, the \a rx regular expression will contain the
804 matched objects (see QRegExp::matchedLength, QRegExp::cap).
805
806 \sa indexOf(), contains(), QRegExp::exactMatch()
807*/
808int QtPrivate::QStringList_lastIndexOf(const QStringList *that, QRegExp &rx, int from)
809{
810 return lastIndexOfMutating(that, rx, from);
811}
812#endif
813
814#if QT_CONFIG(regularexpression)
815/*!
816 \fn int QStringList::indexOf(const QRegularExpression &re, int from) const
817 \overload
818 \since 5.0
819
820 Returns the index position of the first exact match of \a re in
821 the list, searching forward from index position \a from. Returns
822 -1 if no item matched.
823
824 \sa lastIndexOf()
825*/
826int QtPrivate::QStringList_indexOf(const QStringList *that, const QRegularExpression &re, int from)
827{
828 if (from < 0)
829 from = qMax(a: from + that->size(), b: 0);
830
831 QString exactPattern = QRegularExpression::anchoredPattern(expression: re.pattern());
832 QRegularExpression exactRe(exactPattern, re.patternOptions());
833
834 for (int i = from; i < that->size(); ++i) {
835 QRegularExpressionMatch m = exactRe.match(subject: that->at(i));
836 if (m.hasMatch())
837 return i;
838 }
839 return -1;
840}
841
842/*!
843 \fn int QStringList::lastIndexOf(const QRegularExpression &re, int from) const
844 \overload
845 \since 5.0
846
847 Returns the index position of the last exact match of \a re in
848 the list, searching backward from index position \a from. If \a
849 from is -1 (the default), the search starts at the last item.
850 Returns -1 if no item matched.
851
852 \sa indexOf()
853*/
854int QtPrivate::QStringList_lastIndexOf(const QStringList *that, const QRegularExpression &re, int from)
855{
856 if (from < 0)
857 from += that->size();
858 else if (from >= that->size())
859 from = that->size() - 1;
860
861 QString exactPattern = QRegularExpression::anchoredPattern(expression: re.pattern());
862 QRegularExpression exactRe(exactPattern, re.patternOptions());
863
864 for (int i = from; i >= 0; --i) {
865 QRegularExpressionMatch m = exactRe.match(subject: that->at(i));
866 if (m.hasMatch())
867 return i;
868 }
869 return -1;
870}
871#endif // QT_CONFIG(regularexpression)
872
873/*!
874 \fn int QStringList::removeDuplicates()
875
876 \since 4.5
877
878 This function removes duplicate entries from a list.
879 The entries do not have to be sorted. They will retain their
880 original order.
881
882 Returns the number of removed entries.
883*/
884int QtPrivate::QStringList_removeDuplicates(QStringList *that)
885{
886 int n = that->size();
887 int j = 0;
888
889 QDuplicateTracker<QString> seen;
890 seen.reserve(n);
891 for (int i = 0; i < n; ++i) {
892 const QString &s = that->at(i);
893 if (seen.hasSeen(s))
894 continue;
895 if (j != i)
896 that->swapItemsAt(i, j);
897 ++j;
898 }
899 if (n != j)
900 that->erase(afirst: that->begin() + j, alast: that->end());
901 return n - j;
902}
903
904/*! \fn QStringList::QStringList(std::initializer_list<QString> args)
905 \since 4.8
906
907 Construct a list from a std::initializer_list given by \a args.
908
909 This constructor is only enabled if the compiler supports C++11 initializer
910 lists.
911*/
912
913 /*! \fn template<typename InputIterator> QStringList::QStringList(InputIterator first, InputIterator last)
914 \since 5.14
915
916 Constructs a QStringList with the contents in the iterator range [\a first, \a last).
917
918 The value type of \c InputIterator must be convertible to \c QString.
919 */
920
921QT_END_NAMESPACE
922

source code of qtbase/src/corelib/text/qstringlist.cpp