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>
180 QBasicUtf8StringView(
const QByteArray &str)
noexcept;
181 constexpr QBasicUtf8StringView(
const storage_type *d, qsizetype n)
noexcept {};
183 template <
typename String, if_compatible_qstring_like<String> =
true>
185 : QBasicUtf8StringView{str.begin(), str.size()} {}
188 template <
typename Container, if_compatible_container<Container> =
true>
190 : QBasicUtf8StringView(
std::data(c), lengthHelperContainer(c)) {}
192#if defined(__cpp_char8_t) && !defined(Q_QDOC)
193 constexpr QBasicUtf8StringView(QBasicUtf8StringView<!UseChar8T> other)
194 : QBasicUtf8StringView(other.data(), other.size()) {}
197 template <
typename Char, size_t Size, if_compatible_char<Char> =
true>
198 [[nodiscard]]
constexpr static QBasicUtf8StringView
fromArray(
const Char (&string)[Size])
noexcept
199 {
return QBasicUtf8StringView(string, Size); }
206 [[nodiscard]]
const char8_t *utf8()
const noexcept {
return reinterpret_cast<
const char8_t*>(m_data); }
209 [[nodiscard]]
constexpr storage_type
operator[](qsizetype n)
const
210 { verify(n, 1);
return m_data[n]; }
216 [[nodiscard]]
constexpr storage_type
at(qsizetype n)
const {
return (*
this)[n]; }
218 template <
typename...Args>
219 [[nodiscard]]
inline QString arg(Args &&...args)
const;
222 constexpr QBasicUtf8StringView
mid(qsizetype pos, qsizetype n = -1)
const
225 auto result = QContainerImplHelper::mid(size(), &pos, &n);
226 return result == QContainerImplHelper::Null ? QBasicUtf8StringView() : QBasicUtf8StringView(m_data + pos, n);
229 constexpr QBasicUtf8StringView
left(qsizetype n)
const
231 if (size_t(n) >= size_t(size()))
233 return QBasicUtf8StringView(m_data, n);
236 constexpr QBasicUtf8StringView
right(qsizetype n)
const
238 if (size_t(n) >= size_t(size()))
240 return QBasicUtf8StringView(m_data + m_size - n, n);
243 [[nodiscard]]
constexpr QBasicUtf8StringView
sliced(qsizetype pos)
const
244 { verify(pos, 0);
return QBasicUtf8StringView{m_data + pos, m_size - pos}; }
245 [[nodiscard]]
constexpr QBasicUtf8StringView
sliced(qsizetype pos, qsizetype n)
const
246 { verify(pos, n);
return QBasicUtf8StringView(m_data + pos, n); }
247 [[nodiscard]]
constexpr QBasicUtf8StringView
first(qsizetype n)
const
248 { verify(0, n);
return sliced(0, n); }
249 [[nodiscard]]
constexpr QBasicUtf8StringView
last(qsizetype n)
const
250 { verify(0, n);
return sliced(m_size - n, n); }
251 [[nodiscard]]
constexpr QBasicUtf8StringView
chopped(qsizetype n)
const
252 { verify(0, n);
return sliced(0, m_size - n); }
254 constexpr QBasicUtf8StringView &
slice(qsizetype pos)
255 { *
this = sliced(pos);
return *
this; }
256 constexpr QBasicUtf8StringView &
slice(qsizetype pos, qsizetype n)
257 { *
this = sliced(pos, n);
return *
this; }
260 { verify(0, n); m_size = n; }
261 constexpr void chop(qsizetype n)
262 { verify(0, n); m_size -= n; }
266 return QByteArrayView(
reinterpret_cast<
const char *>(data()), size()).isValidUtf8();
281 [[nodiscard]]
constexpr bool empty()
const noexcept {
return size() == 0; }
282 [[nodiscard]]
constexpr storage_type
front()
const {
return Q_ASSERT(!empty()), m_data[0]; }
283 [[nodiscard]]
constexpr storage_type
back()
const {
return Q_ASSERT(!empty()), m_data[m_size - 1]; }
285 [[nodiscard]] Q_IMPLICIT operator std::basic_string_view<storage_type>()
const noexcept
286 {
return std::basic_string_view<storage_type>(data(), size_t(size())); }
288 [[nodiscard]]
constexpr qsizetype max_size()
const noexcept {
return maxSize(); }
293 [[nodiscard]]
constexpr bool isNull()
const noexcept {
return !m_data; }
294 [[nodiscard]]
constexpr bool isEmpty()
const noexcept {
return empty(); }
295 [[nodiscard]]
constexpr qsizetype length()
const noexcept
298 [[nodiscard]]
int compare(QBasicUtf8StringView other,
299 Qt::CaseSensitivity cs = Qt::CaseSensitive)
const noexcept
301 return QtPrivate::compareStrings(*
this, other, cs);
305 [[nodiscard]]
inline int compare(QChar other,
306 Qt::CaseSensitivity cs = Qt::CaseSensitive)
const noexcept;
307 [[nodiscard]]
inline int compare(QStringView other,
309 [[nodiscard]]
inline int compare(QLatin1StringView other,
311 [[nodiscard]]
inline int compare(
const QByteArray &other,
314 [[nodiscard]]
inline bool equal(QChar other)
const noexcept;
315 [[nodiscard]]
inline bool equal(QStringView other)
const noexcept;
316 [[nodiscard]]
inline bool equal(QLatin1StringView other)
const noexcept;
317 [[nodiscard]]
inline bool equal(
const QByteArray &other)
const noexcept;
323 return QtPrivate::MaxAllocSize - 1;
327 [[nodiscard]]
static inline int compare(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs)
noexcept
329 return QtPrivate::compareStrings(QBasicUtf8StringView<
false>(lhs.data(), lhs.size()),
330 QBasicUtf8StringView<
false>(rhs.data(), rhs.size()));
334 comparesEqual(
const QBasicUtf8StringView &lhs,
const QBasicUtf8StringView &rhs)
noexcept
336 return lhs.size() == rhs.size()
337 && QtPrivate::equalStrings(QBasicUtf8StringView<
false>(lhs.data(), lhs.size()),
338 QBasicUtf8StringView<
false>(rhs.data(), rhs.size()));
341 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QBasicUtf8StringView &rhs)
noexcept
343 const int res = QBasicUtf8StringView::compare(lhs, rhs);
344 return Qt::compareThreeWay(res, 0);
346 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView)
349 comparesEqual(
const QBasicUtf8StringView &lhs,
const QLatin1StringView &rhs)
noexcept
351 return lhs.equal(rhs);
353 friend Qt::strong_ordering
354 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QLatin1StringView &rhs)
noexcept
356 const int res = lhs.compare(rhs);
357 return Qt::compareThreeWay(res, 0);
359 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QLatin1StringView)
362 comparesEqual(
const QBasicUtf8StringView &lhs,
const QStringView &rhs)
noexcept
363 {
return lhs.equal(rhs); }
364 friend Qt::strong_ordering
365 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QStringView &rhs)
noexcept
367 const int res = lhs.compare(rhs);
368 return Qt::compareThreeWay(res, 0);
370 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QStringView)
372 friend bool comparesEqual(
const QBasicUtf8StringView &lhs,
const QChar &rhs)
noexcept
373 {
return lhs.equal(rhs); }
374 friend Qt::strong_ordering
375 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QChar &rhs)
noexcept
377 const int res = lhs.compare(rhs);
378 return Qt::compareThreeWay(res, 0);
380 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QChar)
381 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView,
char16_t)
383#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
385 comparesEqual(
const QBasicUtf8StringView &lhs,
const QByteArrayView &rhs)
noexcept
387 return lhs.size() == rhs.size()
388 && QtPrivate::equalStrings(QBasicUtf8StringView<
false>(lhs.data(), lhs.size()),
389 QBasicUtf8StringView<
false>(rhs.data(), rhs.size()));
391 friend Qt::strong_ordering
392 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QByteArrayView &rhs)
noexcept
394 const int res = QtPrivate::compareStrings(QBasicUtf8StringView<
false>(lhs.data(), lhs.size()),
395 QBasicUtf8StringView<
false>(rhs.data(), rhs.size()));
396 return Qt::compareThreeWay(res, 0);
398 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QByteArrayView, QT_ASCII_CAST_WARN)
401 comparesEqual(
const QBasicUtf8StringView &lhs,
const QByteArray &rhs)
noexcept
403 return lhs.equal(rhs);
405 friend Qt::strong_ordering
406 compareThreeWay(
const QBasicUtf8StringView &lhs,
const QByteArray &rhs)
noexcept
408 const int res = lhs.compare(rhs);
409 return Qt::compareThreeWay(res, 0);
411 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QByteArray, QT_ASCII_CAST_WARN)
413 friend bool comparesEqual(
const QBasicUtf8StringView &lhs,
const char *rhs)
noexcept
414 {
return comparesEqual(lhs, QByteArrayView(rhs)); }
415 friend Qt::strong_ordering
416 compareThreeWay(
const QBasicUtf8StringView &lhs,
const char *rhs)
noexcept
417 {
return compareThreeWay(lhs, QByteArrayView(rhs)); }
418 Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView,
const char *, QT_ASCII_CAST_WARN)
421 Q_ALWAYS_INLINE
constexpr void verify([[maybe_unused]] qsizetype pos = 0,
422 [[maybe_unused]] qsizetype n = 1)
const
425 Q_ASSERT(pos <= size());
427 Q_ASSERT(n <= size() - pos);
429 const storage_type *m_data;
434#undef QBasicUtf8StringView
436template <
bool UseChar8T>
439template <
typename QStringLike, std::enable_if_t<std::is_same_v<QStringLike, QByteArray>,
bool> =
true>
441{
return q_no_char8_t::QUtf8StringView(s.begin(), s.size()); }
std::reverse_iterator< const_iterator > const_reverse_iterator
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)
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
const_pointer const_iterator
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
int compare(QStringView other, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
constexpr QBasicUtf8StringView last(qsizetype n) const
const storage_type value_type
static constexpr qsizetype maxSize() noexcept
constexpr QBasicUtf8StringView(std::nullptr_t) noexcept
constexpr storage_type at(qsizetype n) const
value_type * const_pointer
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
value_type & const_reference
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)