1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#ifndef QANYSTRINGVIEWUTILS_P_H
5#define QANYSTRINGVIEWUTILS_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16
17#include <QtCore/private/qjson_p.h>
18
19#include <QtCore/qanystringview.h>
20#include <QtCore/qcbormap.h>
21#include <QtCore/qcborvalue.h>
22
23QT_BEGIN_NAMESPACE
24
25namespace QAnyStringViewUtils {
26
27inline QAnyStringView toStringView(const QCborValue &value)
28{
29 const QCborContainerPrivate *container = QJsonPrivate::Value::container(v: value);
30 if (!container)
31 return QAnyStringView();
32
33 const qint64 n = QJsonPrivate::Value::valueHelper(v: value);
34 const auto &e = container->elements.at(i: n);
35 const auto data = container->byteData(e);
36 if (!data)
37 return QAnyStringView();
38 if (e.flags & QtCbor::Element::StringIsUtf16)
39 return data->asStringView();
40 if (e.flags & QtCbor::Element::StringIsAscii)
41 return data->asLatin1();
42 return data->asUtf8StringView();
43}
44
45inline QAnyStringView toStringView(const QCborMap &map, QLatin1StringView key)
46{
47 return toStringView(value: map[key]);
48}
49
50// Note: This only works if part is US-ASCII, but there is no type to encode this information!
51inline bool endsWith(QAnyStringView whole, QLatin1StringView part)
52{
53 Q_ASSERT(QtPrivate::isAscii(part));
54 return whole.length() >= part.length() && whole.last(n: part.length()) == part;
55}
56
57// Note: This only works if part is US-ASCII, but there is no type to encode this information!
58inline bool startsWith(QAnyStringView whole, QLatin1StringView part)
59{
60 Q_ASSERT(QtPrivate::isAscii(part));
61 return whole.length() >= part.length() && whole.first(n: part.length()) == part;
62}
63
64inline bool doesContain(QStringView whole, QLatin1Char part) { return whole.contains(c: part); }
65inline bool doesContain(QLatin1StringView whole, QLatin1Char part) { return whole.contains(c: part); }
66inline bool doesContain(QUtf8StringView whole, QLatin1Char part)
67{
68 return QByteArrayView(whole.data(), whole.size()).contains(c: part.toLatin1());
69}
70inline bool contains(QAnyStringView whole, QLatin1Char part)
71{
72 return whole.visit(v: [&](auto view) { return doesContain(view, part); });
73}
74
75inline qsizetype getLastIndexOf(QStringView whole, QLatin1StringView part)
76{
77 return whole.lastIndexOf(s: part);
78}
79inline qsizetype getLastIndexOf(QLatin1StringView whole, QLatin1StringView part)
80{
81 return whole.lastIndexOf(s: part);
82}
83inline qsizetype getLastIndexOf(QUtf8StringView whole, QLatin1StringView part)
84{
85 return QByteArrayView(whole.data(), whole.size()).lastIndexOf(a: part);
86}
87inline qsizetype lastIndexOf(QAnyStringView whole, QLatin1StringView part)
88{
89 Q_ASSERT(QtPrivate::isAscii(part));
90 return whole.visit(v: [&](auto view) { return getLastIndexOf(view, part); });
91}
92
93inline int toInt(QUtf8StringView view)
94{
95 return QByteArrayView(view.data(), view.length()).toInt();
96}
97inline int toInt(QLatin1StringView view) { return view.toInt(); }
98inline int toInt(QStringView view) { return view.toInt(); }
99
100inline int toInt(QAnyStringView string)
101{
102 return string.visit(v: [](auto view) { return toInt(view); });
103}
104
105template<typename StringView>
106QAnyStringView doTrimmed(StringView string)
107{
108 if constexpr (std::is_same_v<StringView, QStringView>)
109 return string.trimmed();
110 if constexpr (std::is_same_v<StringView, QLatin1StringView>)
111 return string.trimmed();
112 if constexpr (std::is_same_v<StringView, QUtf8StringView>)
113 return QByteArrayView(string.data(), string.length()).trimmed();
114}
115
116
117inline QAnyStringView trimmed(QAnyStringView string)
118{
119 return string.visit(v: [](auto data) {
120 return doTrimmed(data);
121 });
122}
123
124template<typename StringView, typename Handler>
125auto processAsUtf8(StringView string, Handler &&handler)
126{
127 if constexpr (std::is_same_v<StringView, QStringView>)
128 return handler(QByteArrayView(string.toUtf8()));
129 if constexpr (std::is_same_v<StringView, QLatin1StringView>)
130 return handler(QByteArrayView(string.data(), string.length()));
131 if constexpr (std::is_same_v<StringView, QUtf8StringView>)
132 return handler(QByteArrayView(string.data(), string.length()));
133 if constexpr (std::is_same_v<StringView, QByteArrayView>)
134 return handler(string);
135 if constexpr (std::is_same_v<StringView, QByteArray>)
136 return handler(QByteArrayView(string));
137 if constexpr (std::is_same_v<StringView, QAnyStringView>) {
138
139 // Handler is:
140 // * a reference if an lvalue ref is passed
141 // * a value otherwise
142 // We conserve its nature for passing to the lambda below.
143 // This is necessary because we need to decide on the nature of
144 // the lambda capture as part of the syntax (prefix '&' or not).
145 // So we always pass a reference-conserving wrapper as value.
146 struct Wrapper { Handler handler; };
147
148 return string.visit([w = Wrapper { std::forward<Handler>(handler) }](auto view) mutable {
149 static_assert(!(std::is_same_v<decltype(view), QAnyStringView>));
150 return processAsUtf8(std::move(view), std::forward<Handler>(w.handler));
151 });
152 }
153 Q_UNREACHABLE();
154}
155
156// Note: This only works if sep is US-ASCII, but there is no type to encode this information!
157inline QList<QAnyStringView> split(QAnyStringView source, QLatin1StringView sep)
158{
159 Q_ASSERT(QtPrivate::isAscii(sep));
160
161 QList<QAnyStringView> list;
162 if (source.isEmpty()) {
163 list.append(t: source);
164 return list;
165 }
166
167 qsizetype start = 0;
168 qsizetype end = source.length();
169
170 for (qsizetype current = 0; current < end; ++current) {
171 if (source.mid(pos: current, n: sep.length()) == sep) {
172 list.append(t: source.mid(pos: start, n: current - start));
173 start = current + sep.length();
174 }
175 }
176
177 if (start < end)
178 list.append(t: source.mid(pos: start, n: end - start));
179
180 return list;
181}
182
183}
184
185QT_END_NAMESPACE
186
187#endif // QANYSTRINGVIEWUTILS_P_H
188

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtdeclarative/src/qmltyperegistrar/qanystringviewutils_p.h