4#ifndef QANYSTRINGVIEW_H
5#define QANYSTRINGVIEW_H
7#include <QtCore/qcompare.h>
8#include <QtCore/qcontainerfwd.h>
9#include <QtCore/qlatin1stringview.h>
10#include <QtCore/qstringview.h>
11#include <QtCore/qutf8stringview.h>
13#include <QtCore/q20type_traits.h>
16class tst_QAnyStringView;
22template <
typename Tag,
typename Result>
25template <
typename Tag,
typename Result>
26using wrapped_t =
typename wrapped<Tag, Result>::type;
37#if QT_VERSION >= QT_VERSION_CHECK(7
, 0
, 0
) || defined(QT_BOOTSTRAPPED)
41 static constexpr int SizeShift = 0;
42 static constexpr size_t Latin1Flag =
SizeMask + 1;
44 static constexpr size_t TwoByteCodePointFlag =
Latin1Flag << 1;
46 static_assert(TypeMask == (Latin1Flag|TwoByteCodePointFlag));
58 Utf16 = TwoByteCodePointFlag,
62 template <
typename Char>
68 template <
typename Char>
103 template<
typename Char>
104 static constexpr bool isAsciiOnlyCharsAtCompileTime(Char *str, qsizetype sz)
noexcept
107 if (!q20::is_constant_evaluated())
109 if constexpr (
sizeof(Char) !=
sizeof(
char)) {
114 for (qsizetype i = 0; i < sz; ++i) {
115 if (uchar(str[i]) > 0x7f)
122 template<
typename Char>
123 static constexpr std::size_t encodeType(
const Char *str, qsizetype sz)
noexcept
127 Q_ASSERT(sz <= qsizetype(SizeMask));
128 Q_ASSERT(str || !sz);
129 return (
std::size_t(sz) << SizeShift)
130 | uint(
sizeof(Char) ==
sizeof(
char16_t)) * Tag::Utf16
131 | uint(isAsciiOnlyCharsAtCompileTime(str, sz)) * Tag::Latin1;
134 template <
typename Char>
135 static constexpr qsizetype lengthHelperPointer(
const Char *str)
noexcept
137 if (q20::is_constant_evaluated())
138 return QtPrivate::lengthHelperPointer(str);
139 if constexpr (
sizeof(Char) ==
sizeof(
char16_t))
140 return QtPrivate::qustrlen(
reinterpret_cast<
const char16_t*>(str));
142 return qsizetype(strlen(
reinterpret_cast<
const char*>(str)));
145 static QChar toQChar(
char ch)
noexcept {
return toQChar(QLatin1Char{ch}); }
146 static QChar toQChar(QChar ch)
noexcept {
return ch; }
147 static QChar toQChar(QLatin1Char ch)
noexcept {
return ch; }
149 struct QCharContainer {
150 explicit QCharContainer() =
default;
154 template <
typename Char>
155 static constexpr QAnyStringView fromCharInternal(
const Char &ch)
noexcept
157 if constexpr (
sizeof ch == 1)
158 return QAnyStringView{&ch, 1, size_t{Tag::Latin1}};
163 explicit constexpr QAnyStringView(
const void *d, qsizetype n,
std::size_t sizeAndType)
noexcept
164 :
m_data{d}, m_size{std::size_t(n) | (sizeAndType & TypeMask)} {}
171 template <
typename Char, if_compatible_char<Char> =
true>
177 template <
typename Char, if_compatible_char<Char> =
true>
185 template <
typename Char>
189 template <
typename Pointer, if_compatible_pointer<Pointer> =
true>
203 template <
typename Container, if_convertible_to<QString, Container> =
true>
204 constexpr QAnyStringView(Container &&c, QtPrivate::wrapped_t<Container, QString> &&capacity = {})
208 template <
typename Container, if_convertible_to<QByteArray, Container> =
true>
209 constexpr QAnyStringView(Container &&c, QtPrivate::wrapped_t<Container, QByteArray> &&capacity = {})
213 template <
typename Char, if_compatible_char<Char> =
true>
216 template <
typename Char, if_convertible_to<QChar, Char> =
true>
217 constexpr QAnyStringView(Char ch, QCharContainer &&capacity = QCharContainer())
noexcept
243 auto result = QContainerImplHelper::mid(size(), &pos, &n);
244 return result == QContainerImplHelper::Null ? QAnyStringView() : sliced(pos, n);
249 if (size_t(n) >= size_t(size()))
256 if (size_t(n) >= size_t(size()))
258 return sliced(size() - n, n);
262 { verify(pos, 0);
auto r = *
this; r.advanceData(pos); r.setSize(size() - pos);
return r; }
264 { verify(pos, n);
auto r = *
this; r.advanceData(pos); r.setSize(n);
return r; }
266 { verify(0, n);
return sliced(0, n); }
268 { verify(0, n);
return sliced(size() - n, n); }
270 { verify(0, n);
return sliced(0, size() - n); }
273 { *
this = sliced(pos);
return *
this; }
275 { *
this = sliced(pos, n);
return *
this; }
278 { verify(0, n); setSize(n); }
279 constexpr void chop(qsizetype n)
280 { verify(0, n); setSize(size() - n); }
282 template <
typename...Args>
283 [[nodiscard]]
inline QString arg(Args &&...args)
const;
288 {
return qsizetype((m_size >> SizeShift) & SizeMask); }
289 [[
nodiscard]]
constexpr const void *
data()
const noexcept {
return m_data; }
295#ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
309 {
return size() * charSize(); }
314 return QtPrivate::MaxAllocSize / charSize() - 1;
327 {
return QAnyStringView::equal(lhs, rhs); }
331 const int res = QAnyStringView::compare(lhs, rhs);
332 return Qt::compareThreeWay(res, 0);
336#ifndef QT_NO_DEBUG_STREAM
340 [[
nodiscard]]
constexpr Tag tag()
const noexcept {
return Tag{m_size & TypeMask}; }
341 [[
nodiscard]]
constexpr bool isUtf16()
const noexcept {
return tag() == Tag::Utf16; }
342 [[
nodiscard]]
constexpr bool isUtf8()
const noexcept {
return tag() == Tag::Utf8; }
343 [[
nodiscard]]
constexpr bool isLatin1()
const noexcept {
return tag() == Tag::Latin1; }
344 [[
nodiscard]]
constexpr QStringView asStringView()
const
345 {
return Q_ASSERT(isUtf16()), QStringView{m_data_utf16, size()}; }
346 [[
nodiscard]]
constexpr q_no_char8_t::QUtf8StringView asUtf8StringView()
const
347 {
return Q_ASSERT(isUtf8()), q_no_char8_t::QUtf8StringView{m_data_utf8, size()}; }
348 [[
nodiscard]]
inline constexpr QLatin1StringView asLatin1StringView()
const;
349 [[
nodiscard]]
constexpr size_t charSize()
const noexcept {
return isUtf16() ? 2 : 1; }
350 constexpr void setSize(qsizetype sz)
noexcept { m_size = size_t(sz) | tag(); }
351 constexpr void advanceData(qsizetype delta)
noexcept
352 { m_data_utf8 += delta * charSize(); }
353 Q_ALWAYS_INLINE
constexpr void verify([[maybe_unused]] qsizetype pos = 0,
354 [[maybe_unused]] qsizetype n = 1)
const
357 Q_ASSERT(pos <= size());
359 Q_ASSERT(n <= size() - pos);
367 friend class ::tst_QAnyStringView;
371template <
typename QStringLike, std::enable_if_t<std::disjunction_v<
372 std::is_same<QStringLike, QString>,
373 std::is_same<QStringLike, QByteArray>
375[[nodiscard]]
inline QAnyStringView qToAnyStringViewIgnoringNull(
const QStringLike &s)
noexcept
376{
return QAnyStringView(s.begin(), s.size()); }
constexpr QChar back() const
Returns the last character in the string view.
constexpr const void * data() const noexcept
Returns a const pointer to the first character in the string view.
constexpr QAnyStringView sliced(qsizetype pos, qsizetype n) const
static constexpr bool detects_US_ASCII_at_compile_time
constexpr QAnyStringView left(qsizetype n) const
qsizetype size_type
Alias for qsizetype.
constexpr QAnyStringView(Char ch, QCharContainer &&capacity=QCharContainer()) noexcept
constexpr QAnyStringView & slice(qsizetype pos)
constexpr QAnyStringView last(qsizetype n) const
constexpr qsizetype size() const noexcept
Returns the size of this string view, in the encoding's code points.
constexpr QAnyStringView & slice(qsizetype pos, qsizetype n)
constexpr QAnyStringView(const Char *str, qsizetype len)
Constructs a string view on str with length len.
QString toString() const
Returns a deep copy of this string view's data as a QString.
constexpr QAnyStringView first(qsizetype n) const
constexpr QAnyStringView right(qsizetype n) const
static Q_CORE_EXPORT int compare(QAnyStringView lhs, QAnyStringView rhs, Qt::CaseSensitivity cs=Qt::CaseSensitive) noexcept
Compares the string view lhs with the string view rhs and returns a negative integer if lhs is less t...
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
static Q_CORE_EXPORT bool equal(QAnyStringView lhs, QAnyStringView rhs) noexcept
friend bool comparesEqual(const QAnyStringView &lhs, const QAnyStringView &rhs) noexcept
constexpr qsizetype size_bytes() const noexcept
Returns the size of this string view, but in bytes, not code-points.
constexpr QAnyStringView sliced(qsizetype pos) const
constexpr QAnyStringView mid(qsizetype pos, qsizetype n=-1) const
constexpr QAnyStringView(Container &&c, QtPrivate::wrapped_t< Container, QString > &&capacity={})
constexpr QAnyStringView chopped(qsizetype n) const
constexpr bool isNull() const noexcept
Returns whether this string view is null - that is, whether {data() == nullptr}.
constexpr QAnyStringView() noexcept
Constructs a null string view.
const char16_t * m_data_utf16
constexpr QAnyStringView(const Char *f, const Char *l)
Constructs a string view on first with length (last - first).
constexpr QChar front() const
Returns the first character in the string view.
QString arg(Args &&...args) const
constexpr QAnyStringView(std::nullptr_t) noexcept
Constructs a null string view.
constexpr void chop(qsizetype n)
qptrdiff difference_type
Alias for {std::ptrdiff_t}.
constexpr void truncate(qsizetype n)
constexpr QAnyStringView(QLatin1StringView str) noexcept
constexpr bool empty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
constexpr QAnyStringView(const Pointer &str) noexcept
constexpr qsizetype length() const noexcept
Same as size().
constexpr qsizetype max_size() const noexcept
friend Qt::strong_ordering compareThreeWay(const QAnyStringView &lhs, const QAnyStringView &rhs) noexcept
QAnyStringView(const QByteArray &str) noexcept
Constructs a string view on str.
Combined button and popup list for selecting options.
Q_DECLARE_TYPEINFO(QAnyStringView, Q_PRIMITIVE_TYPE)