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> |
49 | QT_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 | |
267 | namespace { |
268 | struct 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 | |
277 | void 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 | */ |
313 | QStringList 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 |
326 | QStringList 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 | |
338 | template<typename T> |
339 | static 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 |
363 | bool 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 | */ |
379 | bool 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 | */ |
396 | bool 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 | */ |
461 | QStringList 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 | */ |
480 | QStringList 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 | */ |
526 | void 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 |
535 | void 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 | */ |
567 | void 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 | */ |
598 | void 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 | |
605 | static 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 | */ |
633 | QString 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 | */ |
655 | QString 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 | */ |
676 | QString 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 |
719 | static 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 | |
730 | static 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 | */ |
752 | int 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 | */ |
772 | int 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 | */ |
787 | int 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 | */ |
808 | int 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 | */ |
826 | int 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 | */ |
854 | int 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 | */ |
884 | int 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 | |
921 | QT_END_NAMESPACE |
922 | |