3#ifndef QUTF8STRINGVIEW_H
4#define QUTF8STRINGVIEW_H
7#pragma qt_class(QUtf8StringView)
10#include <QtCore/qstringalgorithms.h>
11#include <QtCore/qstringfwd.h>
12#include <QtCore/qarraydata.h>
13#include <QtCore/qbytearrayview.h>
14#include <QtCore/qcompare.h>
15#include <QtCore/qcontainerfwd.h>
19#include <QtCore/q20type_traits.h>
24template <
typename Char>
33template <
typename Char>
37template <
typename Pointer>
38struct IsCompatiblePointer8Helper : std::false_type {};
39template <
typename Char>
40struct IsCompatiblePointer8Helper<Char*>
41 : IsCompatibleChar8Type<Char> {};
46template <
typename T,
typename Enable =
void>
47struct IsContainerCompatibleWithQUtf8StringView : std::false_type {};
86struct wrap_char {
using type =
char; };
91#define QBasicUtf8StringView QUtf8StringView
93template <
bool UseChar8T>
95class QBasicUtf8StringView
99 using storage_type =
typename std::conditional<UseChar8T,
104 using storage_type =
typename QtPrivate::hide_char8_t;
120 template <
typename Char>
121 using if_compatible_char = std::enable_if_t<QtPrivate::IsCompatibleChar8Type<Char>::value,
bool>;
123 template <
typename Pointer>
124 using if_compatible_pointer = std::enable_if_t<QtPrivate::IsCompatiblePointer8<Pointer>::value,
bool>;
126 template <
typename T>
127 using if_compatible_qstring_like = std::enable_if_t<std::is_same_v<T, QByteArray>,
bool>;
129 template <
typename T>
130 using if_compatible_container = std::enable_if_t<QtPrivate::IsContainerCompatibleWithQUtf8StringView<T>::value,
bool>;
132 template <
typename Container>
133 static constexpr qsizetype lengthHelperContainer(
const Container &c)
noexcept
135 return qsizetype(
std::size(c));
140 template <
typename Char, size_t N>
141 static constexpr qsizetype lengthHelperContainer(
const Char (&str)[N])
noexcept
143 return QtPrivate::lengthHelperContainer(str);
146 template <
typename Char>
147 static const storage_type *castHelper(
const Char *str)
noexcept
148 {
return reinterpret_cast<
const storage_type*>(str); }
149 static constexpr const storage_type *castHelper(
const storage_type *str)
noexcept
156 : QBasicUtf8StringView() {}
158 template <
typename Char, if_compatible_char<Char> =
true>
163 template <
typename Char, if_compatible_char<Char> =
true>
165 : QBasicUtf8StringView(f, l - f) {}
168 template <
typename Char, size_t N>
169 constexpr QBasicUtf8StringView(
const Char (&array)[N])
noexcept;
171 template <
typename Char>
172 constexpr QBasicUtf8StringView(
const Char *str)
noexcept;
174 template <
typename Pointer, if_compatible_pointer<Pointer> =
true>
178 template <
typename Char, if_compatible_char<Char> =
true>
180 : QBasicUtf8StringView(&*str) {}
184 QBasicUtf8StringView(
const QByteArray &str)
noexcept;
185 constexpr QBasicUtf8StringView(
const storage_type *d, qsizetype n)
noexcept {};
187 template <
typename String, if_compatible_qstring_like<String> =
true>
189 : QBasicUtf8StringView{str.begin(), str.size()} {}
192 template <
typename Container, if_compatible_container<Container> =
true>
194 : QBasicUtf8StringView(
std::data(c), lengthHelperContainer(c)) {}
196#if defined(__cpp_char8_t) && !defined(Q_QDOC)
197 constexpr QBasicUtf8StringView(QBasicUtf8StringView<!UseChar8T> other)
198 : QBasicUtf8StringView(other.data(), other.size()) {}
201 template <
typename Char, size_t Size, if_compatible_char<Char> =
true>
202 [[nodiscard]]
constexpr static QBasicUtf8StringView
fromArray(
const Char (&string)[Size])
noexcept
203 {
return QBasicUtf8StringView(string, Size); }
210 [[nodiscard]]
const char8_t *utf8()
const noexcept {
return reinterpret_cast<
const char8_t*>(m_data); }
213 [[nodiscard]]
constexpr storage_type
operator[](qsizetype n)
const
214 { verify(n, 1);
return m_data[n]; }
220 [[nodiscard]]
constexpr storage_type
at(qsizetype n)
const {
return (*
this)[n]; }
222 template <
typename...Args>
226 constexpr QBasicUtf8StringView
mid(qsizetype pos, qsizetype n = -1)
const
229 auto result = QContainerImplHelper::mid(size(), &pos, &n);
230 return result == QContainerImplHelper::Null ? QBasicUtf8StringView() : QBasicUtf8StringView(m_data + pos, n);
233 constexpr QBasicUtf8StringView
left(qsizetype n)
const
235 if (size_t(n) >= size_t(size()))
237 return QBasicUtf8StringView(m_data, n);
240 constexpr QBasicUtf8StringView
right(qsizetype n)
const
242 if (size_t(n) >= size_t(size()))
244 return QBasicUtf8StringView(m_data + m_size - n, n);
247 [[nodiscard]]
constexpr QBasicUtf8StringView
sliced(qsizetype pos)
const
248 { verify(pos, 0);
return QBasicUtf8StringView{m_data + pos, m_size - pos}; }
249 [[nodiscard]]
constexpr QBasicUtf8StringView
sliced(qsizetype pos, qsizetype n)
const
250 { verify(pos, n);
return QBasicUtf8StringView(m_data + pos, n); }
251 [[nodiscard]]
constexpr QBasicUtf8StringView
first(qsizetype n)
const
252 { verify(0, n);
return sliced(0, n); }
253 [[nodiscard]]
constexpr QBasicUtf8StringView
last(qsizetype n)
const
254 { verify(0, n);
return sliced(m_size - n, n); }
255 [[nodiscard]]
constexpr QBasicUtf8StringView
chopped(qsizetype n)
const
256 { verify(0, n);
return sliced(0, m_size - n); }
258 constexpr QBasicUtf8StringView &
slice(qsizetype pos)
259 { *
this = sliced(pos);
return *
this; }
260 constexpr QBasicUtf8StringView &
slice(qsizetype pos, qsizetype n)
261 { *
this = sliced(pos, n);
return *
this; }
264 { verify(0, n); m_size = n; }
265 constexpr void chop(qsizetype n)
266 { verify(0, n); m_size -= n; }
270 return QByteArrayView(
reinterpret_cast<
const char *>(data()), size()).isValidUtf8();
285 [[nodiscard]]
constexpr bool empty()
const noexcept {
return size() == 0; }
286 [[nodiscard]]
constexpr storage_type
front()
const {
return Q_ASSERT(!empty()), m_data[0]; }
287 [[nodiscard]]
constexpr storage_type
back()
const {
return Q_ASSERT(!empty()), m_data[m_size - 1]; }
289 [[nodiscard]] Q_IMPLICIT operator std::basic_string_view<storage_type>()
const noexcept
290 {
return std::basic_string_view<storage_type>(data(), size_t(size())); }
292 [[nodiscard]]
constexpr qsizetype max_size()
const noexcept {
return maxSize(); }
297 [[nodiscard]]
constexpr bool isNull()
const noexcept {
return !m_data; }
298 [[nodiscard]]
constexpr bool isEmpty()
const noexcept {
return empty(); }
299 [[nodiscard]]
constexpr qsizetype length()
const noexcept
302 [[nodiscard]]
int compare(QBasicUtf8StringView other,
303 Qt::CaseSensitivity cs = Qt::CaseSensitive)
const noexcept
305 return QtPrivate::compareStrings(*
this, other, cs);
309 [[nodiscard]]
inline int compare(QChar other,
310 Qt::CaseSensitivity cs = Qt::CaseSensitive)
const noexcept;
311 [[nodiscard]]
inline int compare(QStringView other,
313 [[nodiscard]]
inline int compare(QLatin1StringView other,
315 [[nodiscard]]
inline int compare(
const QByteArray &other,
318 [[nodiscard]]
inline bool equal(QChar other)
const noexcept;
319 [[nodiscard]]
inline bool equal(QStringView other)
const noexcept;
320 [[nodiscard]]
inline bool equal(QLatin1StringView other)
const noexcept;
321 [[nodiscard]]
inline bool equal(
const QByteArray &other)
const noexcept;
327 return QtPrivate::MaxAllocSize - 1;
331 [[nodiscard]]
static inline int compare(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs)
noexcept
333 return QtPrivate::compareStrings(QBasicUtf8StringView<
false>(lhs.data(), lhs.size()),
334 QBasicUtf8StringView<
false>(rhs.data(), rhs.size()));
338 comparesEqual(
const QBasicUtf8StringView &lhs,
const QBasicUtf8StringView &rhs)
noexcept
340 return lhs.size() == rhs.size()
341 && QtPrivate::equalStrings(QBasicUtf8StringView<
false>(lhs.data(), lhs.size()),
342 QBasicUtf8StringView<
false>(rhs.data(), rhs.size()));
345 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QBasicUtf8StringView &rhs)
noexcept
347 const int res = QBasicUtf8StringView::compare(lhs, rhs);
348 return Qt::compareThreeWay(res, 0);
350 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView)
353 comparesEqual(
const QBasicUtf8StringView &lhs,
const QLatin1StringView &rhs)
noexcept
355 return lhs.equal(rhs);
357 friend Qt::strong_ordering
358 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QLatin1StringView &rhs)
noexcept
360 const int res = lhs.compare(rhs);
361 return Qt::compareThreeWay(res, 0);
363 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QLatin1StringView)
366 comparesEqual(
const QBasicUtf8StringView &lhs,
const QStringView &rhs)
noexcept
367 {
return lhs.equal(rhs); }
368 friend Qt::strong_ordering
369 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QStringView &rhs)
noexcept
371 const int res = lhs.compare(rhs);
372 return Qt::compareThreeWay(res, 0);
374 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QStringView)
376 friend bool comparesEqual(
const QBasicUtf8StringView &lhs,
const QChar &rhs)
noexcept
377 {
return lhs.equal(rhs); }
378 friend Qt::strong_ordering
379 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QChar &rhs)
noexcept
381 const int res = lhs.compare(rhs);
382 return Qt::compareThreeWay(res, 0);
384 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QChar)
385 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView,
char16_t)
387#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
389 comparesEqual(
const QBasicUtf8StringView &lhs,
const QByteArrayView &rhs)
noexcept
391 return lhs.size() == rhs.size()
392 && QtPrivate::equalStrings(QBasicUtf8StringView<
false>(lhs.data(), lhs.size()),
393 QBasicUtf8StringView<
false>(rhs.data(), rhs.size()));
395 friend Qt::strong_ordering
396 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QByteArrayView &rhs)
noexcept
398 const int res = QtPrivate::compareStrings(QBasicUtf8StringView<
false>(lhs.data(), lhs.size()),
399 QBasicUtf8StringView<
false>(rhs.data(), rhs.size()));
400 return Qt::compareThreeWay(res, 0);
402 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QByteArrayView, QT_ASCII_CAST_WARN)
405 comparesEqual(
const QBasicUtf8StringView &lhs,
const QByteArray &rhs)
noexcept
407 return lhs.equal(rhs);
409 friend Qt::strong_ordering
410 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QByteArray &rhs)
noexcept
412 const int res = lhs.compare(rhs);
413 return Qt::compareThreeWay(res, 0);
415 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QByteArray, QT_ASCII_CAST_WARN)
417 friend bool comparesEqual(
const QBasicUtf8StringView &lhs,
const char *rhs)
noexcept
418 {
return comparesEqual(lhs, QByteArrayView(rhs)); }
419 friend Qt::strong_ordering
420 compareThreeWay(
const QBasicUtf8StringView &lhs,
const char *rhs)
noexcept
421 {
return compareThreeWay(lhs, QByteArrayView(rhs)); }
422 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView,
const char *, QT_ASCII_CAST_WARN)
425 Q_ALWAYS_INLINE
constexpr void verify([[maybe_unused]] qsizetype pos = 0,
426 [[maybe_unused]] qsizetype n = 1)
const
429 Q_ASSERT(pos <= size());
431 Q_ASSERT(n <= size() - pos);
433 const storage_type *m_data;
438#undef QBasicUtf8StringView
440template <
bool UseChar8T>
443template <
typename QStringLike, std::enable_if_t<std::is_same_v<QStringLike, QByteArray>,
bool> =
true>
445{
return q_no_char8_t::QUtf8StringView(s.begin(), s.size()); }
constexpr QBasicUtf8StringView mid(qsizetype pos, qsizetype n=-1) const
const_reverse_iterator crend() const noexcept
constexpr QBasicUtf8StringView & slice(qsizetype pos, qsizetype n)
constexpr QBasicUtf8StringView first(qsizetype n) const
constexpr bool empty() const noexcept
constexpr void truncate(qsizetype n)
value_type & const_reference
constexpr QBasicUtf8StringView(const Char *f, const Char *l)
constexpr QBasicUtf8StringView(const Pointer &str) noexcept
constexpr qsizetype size() const noexcept
constexpr QBasicUtf8StringView(const Char *str, qsizetype len)
const_reverse_iterator rbegin() const noexcept
constexpr QBasicUtf8StringView sliced(qsizetype pos) const
bool isValidUtf8() const noexcept
bool equal(QChar other) const noexcept
const_iterator begin() const noexcept
QString arg(Args &&...args) const
static constexpr QBasicUtf8StringView fromArray(const Char(&string)[Size]) noexcept
constexpr QBasicUtf8StringView & slice(qsizetype pos)
constexpr storage_type operator[](qsizetype n) const
friend Qt::strong_ordering compareThreeWay(const QBasicUtf8StringView &lhs, const QBasicUtf8StringView &rhs) noexcept
bool equal(const QByteArray &other) const noexcept
friend bool comparesEqual(const QBasicUtf8StringView &lhs, const QBasicUtf8StringView &rhs) noexcept
const_iterator cend() const noexcept
constexpr storage_type back() const
constexpr QBasicUtf8StringView sliced(qsizetype pos, qsizetype n) const
const_reverse_iterator rend() const noexcept
int compare(const QByteArray &other, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
std::reverse_iterator< const_iterator > const_reverse_iterator
value_type * const_pointer
const_pointer const_iterator
int compare(QStringView other, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
constexpr QBasicUtf8StringView last(qsizetype n) const
static constexpr qsizetype maxSize() noexcept
constexpr QBasicUtf8StringView(std::nullptr_t) noexcept
constexpr storage_type at(qsizetype n) const
const storage_type value_type
constexpr QBasicUtf8StringView(const Char(&str)[]) noexcept
constexpr storage_type front() const
constexpr QBasicUtf8StringView left(qsizetype n) const
constexpr QBasicUtf8StringView() noexcept
const_iterator end() const noexcept
constexpr void chop(qsizetype n)
const_reverse_iterator crbegin() const noexcept
const_iterator cbegin() const noexcept
constexpr const_pointer data() const noexcept
constexpr QBasicUtf8StringView right(qsizetype n) const
constexpr QBasicUtf8StringView chopped(qsizetype n) const
q_no_char8_t::QUtf8StringView qToUtf8StringViewIgnoringNull(const QStringLike &s) noexcept
Q_DECLARE_TYPEINFO_BODY(QBasicUtf8StringView< UseChar8T >, Q_PRIMITIVE_TYPE)