Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qanystringview.cpp
Go to the documentation of this file.
1// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5#include "qdebug.h"
6#include "qttypetraits.h"
7
9
10/*!
11 \class QAnyStringView
12 \inmodule QtCore
13 \since 6.0
14 \brief The QAnyStringView class provides a unified view on Latin-1, UTF-8,
15 or UTF-16 strings with a read-only subset of the QString API.
16 \reentrant
17 \ingroup tools
18 \ingroup string-processing
19
20 \compares strong
21 \compareswith strong char16_t QChar {const char16_t *} {const char *} \
22 QByteArray QByteArrayView QString QStringView QUtf8StringView \
23 QLatin1StringView
24 \endcompareswith
25
26 A QAnyStringView references a contiguous portion of a string it does
27 not own. It acts as an interface type to all kinds of strings,
28 without the need to construct a QString first.
29
30 Unlike QStringView and QUtf8StringView, QAnyStringView can hold
31 strings of any of the following encodings: UTF-8, UTF-16, and
32 Latin-1. The latter is supported because Latin-1, unlike UTF-8,
33 can be efficiently compared to UTF-16 data: a length mismatch
34 already means the strings cannot be equal. This is not true for
35 UTF-8/UTF-16 comparisons, because UTF-8 is a variable-length
36 encoding.
37
38 The string may be represented as an array (or an array-compatible
39 data-structure such as QString, std::basic_string, etc.) of \c
40 char, \c char8_t, QChar, \c ushort, \c char16_t or (on platforms,
41 such as Windows, where it is a 16-bit type) \c wchar_t.
42
43 QAnyStringView is designed as an interface type; its main use-case
44 is as a function parameter type. When QAnyStringViews are used as
45 automatic variables or data members, care must be taken to ensure
46 that the referenced string data (for example, owned by a QString)
47 outlives the QAnyStringView on all code paths, lest the string
48 view ends up referencing deleted data.
49
50 When used as an interface type, QAnyStringView allows a single
51 function to accept a wide variety of string data sources. One
52 function accepting QAnyStringView thus replaces five function
53 overloads (taking QString, \c{(const QChar*, qsizetype)},
54 QUtf8StringView, QLatin1StringView (but see above), and QChar), while
55 at the same time enabling even more string data sources to be
56 passed to the function, such as \c{u8"Hello World"}, a \c char8_t
57 string literal.
58
59 Like elsewhere in Qt, QAnyStringView assumes \c char data is encoded
60 in UTF-8, unless it is presented as a QLatin1StringView.
61
62 Since Qt 6.4, however, UTF-8 string literals that are pure US-ASCII are
63 automatically stored as Latin-1. This is a compile-time check with no
64 runtime overhead. The feature requires compiling in C++20, or with a recent
65 GCC.
66
67 QAnyStringViews should be passed by value, not by reference-to-const:
68 \snippet code/src_corelib_text_qanystringview.cpp 0
69
70 QAnyStringView can also be used as the return value of a function,
71 but this is not recommended. QUtf8StringView or QStringView are
72 better suited as function return values. If you call a function
73 returning QAnyStringView, take extra care to not keep the
74 QAnyStringView around longer than the function promises to keep
75 the referenced string data alive. If in doubt, obtain a strong
76 reference to the data by calling toString() to convert the
77 QAnyStringView into a QString.
78
79 QAnyStringView is a \e{Literal Type}.
80
81 \section2 Compatible Character Types
82
83 QAnyStringView accepts strings over a variety of character types:
84
85 \list
86 \li \c char (both signed and unsigned)
87 \li \c char8_t (C++20 only)
88 \li \c char16_t
89 \li \c wchar_t (where it's a 16-bit type, e.g. Windows)
90 \li \c ushort
91 \li \c QChar
92 \endlist
93
94 The 8-bit character types are interpreted as UTF-8 data (except when
95 presented as a QLatin1StringView) while the 16-bit character types are
96 interpreted as UTF-16 data in host byte order (the same as QString).
97
98 \section2 Sizes and Sub-Strings
99
100 All sizes and positions in QAnyStringView functions are in the
101 encoding's code units (that is, UTF-16 surrogate pairs count as
102 two for the purposes of these functions, the same as in QString,
103 and UTF-8 multibyte sequences count as two, three or four,
104 depending on their length).
105
106 \sa QUtf8StringView, QStringView
107*/
108
109/*!
110 \typedef QAnyStringView::difference_type
111
112 Alias for \c{std::ptrdiff_t}. Provided for compatibility with the STL.
113*/
114
115/*!
116 \typedef QAnyStringView::size_type
117
118 Alias for qsizetype. Provided for compatibility with the STL.
119*/
120
121/*!
122 \fn QAnyStringView::QAnyStringView()
123
124 Constructs a null string view.
125
126 \sa isNull()
127*/
128
129/*!
130 \fn QAnyStringView::QAnyStringView(std::nullptr_t)
131
132 Constructs a null string view.
133
134 \sa isNull()
135*/
136
137/*!
138 \fn template <typename Char, QAnyStringView::if_compatible_char<Char> = true> QAnyStringView::QAnyStringView(const Char *str, qsizetype len)
139
140 Constructs a string view on \a str with length \a len.
141
142 The range \c{[str,len)} must remain valid for the lifetime of this string view object.
143
144 Passing \nullptr as \a str is safe if \a len is 0, too, and results in a null string view.
145
146 The behavior is undefined if \a len is negative or, when positive, if \a str is \nullptr.
147
148 \constraints \c Char is a compatible character type.
149
150 \sa isNull(), {Compatible Character Types}
151*/
152
153/*!
154 \fn template <typename Char, QAnyStringView::if_compatible_char<Char> = true> QAnyStringView::QAnyStringView(const Char *first, const Char *last)
155
156 Constructs a string view on \a first with length (\a last - \a first).
157
158 The range \c{[first,last)} must remain valid for the lifetime of
159 this string view object.
160
161 Passing \nullptr as \a first is safe if \a last is \nullptr, too,
162 and results in a null string view.
163
164 The behavior is undefined if \a last precedes \a first, or \a first
165 is \nullptr and \a last is not.
166
167 \constraints \c Char is a compatible character type.
168
169 \sa isNull(), {Compatible Character Types}
170*/
171
172/*!
173 \fn template <typename Char> QAnyStringView::QAnyStringView(const Char *str)
174
175 Constructs a string view on \a str. The length is determined
176 by scanning for the first \c{Char(0)}.
177
178 \a str must remain valid for the lifetime of this string view object.
179
180 Passing \nullptr as \a str is safe and results in a null string view.
181
182 \constraints \a str is not an array and \c Char is a
183 compatible character type.
184
185 \sa isNull(), {Compatible Character Types}
186*/
187
188/*!
189 \fn template <typename Char, size_t N> QAnyStringView::QAnyStringView(const Char (&string)[N])
190
191 Constructs a string view on the character string literal \a string.
192 The view covers the array until the first \c{Char(0)} is encountered,
193 or \c N, whichever comes first.
194 If you need the full array, use fromArray() instead.
195
196 \a string must remain valid for the lifetime of this string view
197 object.
198
199 \constraints \a
200 string is an actual array and \c Char is a compatible character
201 type.
202
203 \sa {Compatible Character Types}
204*/
205
206/*!
207 \fn QAnyStringView::QAnyStringView(const QString &str)
208
209 Constructs a string view on \a str.
210
211 \c{str.data()} must remain valid for the lifetime of this string view object.
212
213 The string view will be null if and only if \c{str.isNull()}.
214*/
215
216/*!
217 \fn QAnyStringView::QAnyStringView(const QByteArray &str)
218
219 Constructs a string view on \a str. The data in \a str is interpreted as UTF-8.
220
221 \c{str.data()} must remain valid for the lifetime of this string view object.
222
223 The string view will be null if and only if \c{str.isNull()}.
224*/
225
226/*!
227 \fn template <typename Container, QAnyStringView::if_compatible_container<Container>> QAnyStringView::QAnyStringView(const Container &str)
228
229 Constructs a string view on \a str. The length is taken from \c{std::size(str)}.
230
231 \c{std::data(str)} must remain valid for the lifetime of this string view object.
232
233 The string view will be empty if and only if \c{std::size(str) == 0}. It is unspecified
234 whether this constructor can result in a null string view (\c{std::data(str)} would
235 have to return \nullptr for this).
236
237 \constraints \c Container is a
238 container with a compatible character type as \c{value_type}.
239
240 \sa isNull(), isEmpty()
241*/
242
243/*!
244 \fn template <typename Char, size_t Size> static QAnyStringView fromArray(const Char (&string)[Size]) noexcept
245
246 Constructs a string view on the full character string literal \a string,
247 including any trailing \c{Char(0)}. If you don't want the
248 null-terminator included in the view then you can use the constructor
249 overload taking a pointer and a size:
250
251 \snippet code/src_corelib_text_qanystringview.cpp 2
252
253 Alternatively you can use the constructor overload taking an
254 array literal which will create a view up to, but not including,
255 the first null-terminator in the data.
256
257 \a string must remain valid for the lifetime of this string view
258 object.
259
260 This function will work with any array literal if \c Char is a
261 compatible character type.
262*/
263
264/*!
265 \fn QString QAnyStringView::toString() const
266
267 Returns a deep copy of this string view's data as a QString.
268
269 The return value will be a null QString if and only if this string view is null.
270*/
271
272/*!
273 \fn const void *QAnyStringView::data() const
274
275 Returns a const pointer to the first character in the string view.
276
277 \note The character array represented by the return value is \e not null-terminated.
278
279 \sa size_bytes()
280*/
281
282/*!
283 \fn bool QAnyStringView::empty() const
284
285 Returns whether this string view is empty - that is, whether \c{size() == 0}.
286
287 This function is provided for STL compatibility.
288
289 \sa isEmpty(), isNull(), size()
290*/
291
292/*!
293 \fn bool QAnyStringView::isEmpty() const
294
295 Returns whether this string view is empty - that is, whether \c{size() == 0}.
296
297 This function is provided for compatibility with other Qt containers.
298
299 \sa empty(), isNull(), size()
300*/
301
302/*!
303 \fn bool QAnyStringView::isNull() const
304
305 Returns whether this string view is null - that is, whether \c{data() == nullptr}.
306
307 This functions is provided for compatibility with other Qt containers.
308
309 \sa empty(), isEmpty(), size()
310*/
311
312/*!
313 \fn qsizetype QAnyStringView::size() const
314
315 Returns the size of this string view, in the encoding's code points.
316
317 \sa empty(), isEmpty(), isNull(), size_bytes(), {Sizes and Sub-Strings}
318*/
319
320/*!
321 \fn QAnyStringView::size_bytes() const
322
323 Returns the size of this string view, but in bytes, not code-points.
324
325 You can use this function together with data() for hashing or serialization.
326
327 This function is provided for STL compatibility.
328
329 \sa size(), data()
330*/
331
332/*!
333 \fn QAnyStringView::length() const
334
335 Same as size().
336
337 This function is provided for compatibility with other Qt containers.
338
339 \sa size()
340*/
341
342/*!
343 \fn QChar QAnyStringView::front() const
344
345 Returns the first character in the string view.
346
347 This function is provided for STL compatibility.
348
349 \warning Calling this function on an empty string view constitutes
350 undefined behavior.
351
352 \sa back(), {Sizes and Sub-Strings}
353*/
354
355/*!
356 \fn QChar QAnyStringView::back() const
357
358 Returns the last character in the string view.
359
360 This function is provided for STL compatibility.
361
362 \warning Calling this function on an empty string view constitutes
363 undefined behavior.
364
365 \sa front(), {Sizes and Sub-Strings}
366*/
367
368/*!
369 \fn QAnyStringView::mid(qsizetype pos, qsizetype n) const
370 \since 6.5
371
372 Returns the substring of length \a n starting at position
373 \a pos in this object.
374
375 \deprecated Use sliced() instead in new code.
376
377 Returns an empty string view if \a n exceeds the
378 length of the string view. If there are less than \a n code points
379 available in the string view starting at \a pos, or if
380 \a n is negative (default), the function returns all code points that
381 are available from \a pos.
382
383 \sa first(), last(), sliced(), chopped(), chop(), truncate(), slice(), {Sizes and Sub-Strings}
384*/
385
386/*!
387 \fn QAnyStringView::left(qsizetype n) const
388 \since 6.5
389
390 \deprecated Use first() instead in new code.
391
392 Returns the substring of length \a n starting at position
393 0 in this object.
394
395 The entire string view is returned if \a n is greater than or equal
396 to size(), or less than zero.
397
398 \sa first(), last(), sliced(), chopped(), chop(), truncate(), slice(), {Sizes and Sub-Strings}
399*/
400
401/*!
402 \fn QAnyStringView::right(qsizetype n) const
403 \since 6.5
404
405 \deprecated Use last() instead in new code.
406
407 Returns the substring of length \a n starting at position
408 size() - \a n in this object.
409
410 The entire string view is returned if \a n is greater than or equal
411 to size(), or less than zero.
412
413 \sa first(), last(), sliced(), chopped(), chop(), truncate(), slice(), {Sizes and Sub-Strings}
414*/
415
416/*!
417 \fn QAnyStringView::first(qsizetype n) const
418 \since 6.5
419
420 Returns a string view that contains the first \a n code points
421 of this string view.
422
423 \note The behavior is undefined when \a n < 0 or \a n > size().
424
425 \sa last(), sliced(), chopped(), chop(), truncate(), slice(), {Sizes and Sub-Strings}
426*/
427
428/*!
429 \fn QAnyStringView::last(qsizetype n) const
430 \since 6.5
431
432 Returns a string view that contains the last \a n code points of this string view.
433
434 \note The behavior is undefined when \a n < 0 or \a n > size().
435
436 \sa first(), sliced(), chopped(), chop(), truncate(), slice(), {Sizes and Sub-Strings}
437*/
438
439/*!
440 \fn QAnyStringView::sliced(qsizetype pos, qsizetype n) const
441 \since 6.5
442
443 Returns a string view containing \a n code points of this string view,
444 starting at position \a pos.
445
446//! [UB-sliced-index-length]
447 \note The behavior is undefined when \a pos < 0, \a n < 0,
448 or \a pos + \a n > size().
449//! [UB-sliced-index-length]
450
451 \sa first(), last(), chopped(), chop(), truncate(), slice(), {Sizes and Sub-Strings}
452*/
453
454/*!
455 \fn QAnyStringView::sliced(qsizetype pos) const
456 \since 6.5
457
458 Returns a string view starting at position \a pos in this object,
459 and extending to its end.
460
461//! [UB-sliced-index-only]
462 \note The behavior is undefined when \a pos < 0 or \a pos > size().
463//! [UB-sliced-index-only]
464
465 \sa first(), last(), chopped(), chop(), truncate(), slice(), {Sizes and Sub-Strings}
466*/
467
468/*!
469 \fn QAnyStringView &QAnyStringView::slice(qsizetype pos, qsizetype n)
470 \since 6.8
471
472 Modifies this string view to start at position \a pos, extending for
473 \a n code points.
474
475 \include qanystringview.cpp UB-sliced-index-length
476
477 \sa sliced(), first(), last(), chopped(), chop(), truncate(), {Sizes and Sub-Strings}
478*/
479
480/*!
481 \fn QAnyStringView &QAnyStringView::slice(qsizetype pos)
482 \since 6.8
483 \overload
484
485 Modifies this string view to start at position \a pos, extending to
486 its end.
487
488 \include qanystringview.cpp UB-sliced-index-only
489
490 \sa sliced(), first(), last(), chopped(), chop(), truncate(), {Sizes and Sub-Strings}
491*/
492
493/*!
494 \fn QAnyStringView::chopped(qsizetype n) const
495 \since 6.5
496
497 Returns the substring of length size() - \a n starting at the
498 beginning of this object.
499
500 Same as \c{first(size() - n)}.
501
502 \note The behavior is undefined when \a n < 0 or \a n > size().
503
504 \sa sliced(), first(), last(), chop(), truncate(), slice(), {Sizes and Sub-Strings}
505*/
506
507/*!
508 \fn QAnyStringView::truncate(qsizetype n)
509 \since 6.5
510
511 Truncates this string view to \a n code points.
512
513 Same as \c{*this = first(n)}.
514
515 \note The behavior is undefined when \a n < 0 or \a n > size().
516
517 \sa sliced(), first(), last(), chopped(), chop(), {Sizes and Sub-Strings}
518*/
519
520/*!
521 \fn QAnyStringView::chop(qsizetype n)
522 \since 6.5
523
524 Truncates this string view by \a n code points.
525
526 Same as \c{*this = first(size() - n)}.
527
528 \note The behavior is undefined when \a n < 0 or \a n > size().
529
530 \sa sliced(), first(), last(), chopped(), truncate(), slice(), {Sizes and Sub-Strings}
531*/
532
533/*! \fn template <typename Visitor> decltype(auto) QAnyStringView::visit(Visitor &&v) const
534
535 Calls \a v with either a QUtf8StringView, QLatin1String, or QStringView, depending
536 on the encoding of the string data this string-view references.
537
538 This is how most functions taking QAnyStringView fork off into per-encoding
539 functions:
540
541 \code
542 void processImpl(QLatin1String s) { ~~~ }
543 void processImpl(QUtf8StringView s) { ~~~ }
544 void processImpl(QStringView s) { ~~~ }
545
546 void process(QAnyStringView s)
547 {
548 s.visit([](auto s) { processImpl(s); });
549 }
550 \endcode
551
552 Here, we're reusing the same name, \c s, for both the QAnyStringView
553 object, as well as the lambda's parameter. This is idiomatic code and helps
554 track the identity of the objects through visit() calls, for example in more
555 complex situations such as
556
557 \code
558 bool equal(QAnyStringView lhs, QAnyStringView rhs)
559 {
560 // assuming operator==(QAnyStringView, QAnyStringView) didn't, yet, exist:
561 return lhs.visit([rhs](auto lhs) {
562 rhs.visit([lhs](auto rhs) {
563 return lhs == rhs;
564 });
565 });
566 }
567 \endcode
568
569 visit() requires that all lambda instantiations have the same return type.
570 If they differ, you get a compile error, even if there is a common type. To
571 fix, you can use explicit return types on the lambda, or cast in the return
572 statements:
573
574 \code
575 // wrong:
576 QAnyStringView firstHalf(QAnyStringView input)
577 {
578 return input.visit([](auto input) { // ERROR: lambdas return different types
579 return input.sliced(0, input.size() / 2);
580 });
581 }
582 // correct:
583 QAnyStringView firstHalf(QAnyStringView input)
584 {
585 return input.visit([](auto input) -> QAnyStringView { // OK, explicit return type
586 return input.sliced(0, input.size() / 2);
587 });
588 }
589 // also correct:
590 QAnyStringView firstHalf(QAnyStringView input)
591 {
592 return input.visit([](auto input) {
593 return QAnyStringView(input.sliced(0, input.size() / 2)); // OK, cast to common type
594 });
595 }
596 \endcode
597*/
598
599/*!
600 \fn QAnyStringView::compare(QAnyStringView lhs, QAnyStringView rhs, Qt::CaseSensitivity cs)
601
602 Compares the string view \a lhs with the string view \a rhs and returns a
603 negative integer if \a lhs is less than \a rhs, a positive integer if it is
604 greater than \a rhs, and zero if they are equal.
605
606 If \a cs is Qt::CaseSensitive (the default), the comparison is case sensitive;
607 otherwise the comparison is case-insensitive.
608
609 \sa operator==(), operator<(), operator>()
610*/
611
612/*!
613 \fn bool QAnyStringView::operator==(const QAnyStringView &lhs, const QAnyStringView & rhs)
614 \fn bool QAnyStringView::operator!=(const QAnyStringView & lhs, const QAnyStringView & rhs)
615 \fn bool QAnyStringView::operator<=(const QAnyStringView & lhs, const QAnyStringView & rhs)
616 \fn bool QAnyStringView::operator>=(const QAnyStringView & lhs, const QAnyStringView & rhs)
617 \fn bool QAnyStringView::operator<(const QAnyStringView & lhs, const QAnyStringView & rhs)
618 \fn bool QAnyStringView::operator>(const QAnyStringView & lhs, const QAnyStringView & rhs)
619
620 Operators that compare \a lhs to \a rhs.
621
622 \sa compare()
623*/
624
625/*!
626 \fn template <typename QStringLike> qToAnyStringViewIgnoringNull(const QStringLike &s);
627 \since 6.0
628 \internal
629
630 Convert \a s to a QAnyStringView ignoring \c{s.isNull()}.
631
632 Returns a string view that references \a{s}'s data, but is never null.
633
634 This is a faster way to convert a QString or QByteArray to a QAnyStringView,
635 if null QStrings or QByteArrays can legitimately be treated as empty ones.
636
637 \sa QString::isNull(), QAnyStringView
638*/
639
640/*!
641 \fn QAnyStringView::max_size() const
642 \since 6.8
643
644 This function is provided for STL compatibility.
645
646 It returns the maximum number of elements that the string view can
647 theoretically represent. In practice, the number can be much smaller,
648 limited by the amount of memory available to the system.
649
650 \note The returned value is calculated based on the currently used character
651 type, so calling this function on two different views may return different
652 results.
653*/
654
655/*!
656 \fn QAnyStringView::operator<<(QDebug d, QAnyStringView s)
657 \since 6.7
658 \relates QDebug
659
660 Outputs \a s to debug stream \a d.
661
662 If \c{d.quotedString()} is \c true, indicates which encoding the string is
663 in. If you just want the string data, use visit() like this:
664
665 \code
666 s.visit([&d) (auto s) { d << s; });
667 \endcode
668
669 \sa QAnyStringView::visit()
670*/
671QDebug operator<<(QDebug d, QAnyStringView s)
672{
673 struct S { const char *prefix, *suffix; };
674 const auto affixes = s.visit([](auto s) {
675 using View = decltype(s);
676 if constexpr (std::is_same_v<View, QLatin1StringView>) {
677 return S{"", "_L1"};
678 } else if constexpr (std::is_same_v<View, QUtf8StringView>) {
679 return S{"u8", ""};
680 } else if constexpr (std::is_same_v<View, QStringView>) {
681 return S{"u", ""};
682 } else {
683 static_assert(QtPrivate::type_dependent_false<View>());
684 }
685 });
686 const QDebugStateSaver saver(d);
687 d.nospace();
688 if (d.quoteStrings())
689 d << affixes.prefix;
690 s.visit([&d](auto s) { d << s; });
691 if (d.quoteStrings())
692 d << affixes.suffix;
693 return d;
694}
695
696/*!
697 \fn template <typename...Args> QString QAnyStringView::arg(Args &&...args) const
698 \since 6.9
699
700 \include qstringview.cpp qstring-multi-arg
701
702 \sa QString::arg(Args&&...)
703*/
704
705/*!
706 \fn template <typename Char, size_t Size, QAnyStringView::if_compatible_char<Char>> QAnyStringView QAnyStringView::fromArray(const Char (&string)[Size])
707
708 Constructs a string view on the full character string literal \a string,
709 including any trailing \c{Char(0)}. If you don't want the
710 null-terminator included in the view then you can chop() it off
711 when you are certain it is at the end. Alternatively you can use
712 the constructor overload taking an array literal which will create
713 a view up to, but not including, the first null-terminator in the data.
714
715 \a string must remain valid for the lifetime of this string view
716 object.
717
718 This function will work with any array literal if \c Char is a
719 compatible character type. The compatible character types are: \c QChar, \c ushort, \c
720 char16_t and (on platforms, such as Windows, where it is a 16-bit
721 type) \c wchar_t.
722*/
723
724QT_END_NAMESPACE
Combined button and popup list for selecting options.