4#ifndef QANYSTRINGVIEW_H
5#define QANYSTRINGVIEW_H
7#include <QtCore/qcompare.h>
8#include <QtCore/qlatin1stringview.h>
9#include <QtCore/qstringview.h>
10#include <QtCore/qutf8stringview.h>
12#ifdef __cpp_impl_three_way_comparison
15#include <QtCore/q20type_traits.h>
18class tst_QAnyStringView;
24template <
typename Tag,
typename Result>
27template <
typename Tag,
typename Result>
38 static constexpr size_t SizeMask = (std::numeric_limits<size_t>::max)() / 4;
39#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) || defined(QT_BOOTSTRAPPED)
40 static constexpr int SizeShift = 2;
41 static constexpr size_t Latin1Flag = 1;
43 static constexpr int SizeShift = 0;
44 static constexpr size_t Latin1Flag = SizeMask + 1;
46 static constexpr size_t TwoByteCodePointFlag = Latin1Flag << 1;
47 static constexpr size_t TypeMask = ~(SizeMask << SizeShift);
48 static_assert(TypeMask == (Latin1Flag|TwoByteCodePointFlag));
60 Utf16 = TwoByteCodePointFlag,
64 template <
typename Char>
65 using is_compatible_char = std::disjunction<
70 template <
typename Char>
71 using if_compatible_char = std::enable_if_t<is_compatible_char<Char>::value,
bool>;
73 template <
typename Po
inter>
74 using if_compatible_pointer = std::enable_if_t<std::disjunction_v<
81 using if_compatible_container = std::enable_if_t<std::disjunction_v<
86 template <
typename QStringOrQByteArray,
typename T>
87 using if_convertible_to = std::enable_if_t<std::conjunction_v<
89 std::negation<std::disjunction<
90 std::is_same<q20::remove_cvref_t<T>, QAnyStringView::Tag>,
92 std::is_pointer<std::decay_t<T>>,
93 is_compatible_char<T>,
94 std::is_same<q20::remove_cvref_t<T>,
QByteArray>,
95 std::is_same<q20::remove_cvref_t<T>,
QString>
98 std::is_convertible<T, QStringOrQByteArray>
105 template<
typename Char>
106 static constexpr bool isAsciiOnlyCharsAtCompileTime(
Char *
str,
qsizetype sz)
noexcept
111 if constexpr (
sizeof(
Char) !=
sizeof(
char)) {
124 template<
typename Char>
125 static constexpr std::size_t encodeType(
const Char *
str,
qsizetype sz)
noexcept
131 return (std::size_t(sz) << SizeShift)
132 |
uint(
sizeof(
Char) ==
sizeof(
char16_t)) * Tag::Utf16
133 |
uint(isAsciiOnlyCharsAtCompileTime(
str, sz)) * Tag::Latin1;
136 template <
typename Char>
141 if constexpr (
sizeof(
Char) ==
sizeof(
char16_t))
144 return qsizetype(strlen(
reinterpret_cast<const char*
>(
str)));
151 struct QCharContainer {
152 explicit QCharContainer() =
default;
160 :
m_data{
nullptr}, m_size{0} {}
164 template <
typename Char, if_compatible_
char<Char> = true>
170 template <
typename Char, if_compatible_
char<Char> = true>
175 template <
typename Char,
size_t N>
178 template <
typename Char>
182 template <
typename Po
inter, if_compatible_po
inter<Po
inter> = true>
192 template <
typename Container, if_compatible_container<Container> = true>
196 template <
typename Container, if_convertible_to<QString, Container> = true>
201 template <
typename Container, if_convertible_to<QByteArray, Container> = true>
205 template <
typename Char, if_compatible_
char<Char> = true>
208 template <
typename Char, if_convertible_to<QChar, Char> = true>
212 template <
typename Char,
typename Container =
decltype(QChar::fromUcs4(U
'x')),
213 std::enable_if_t<std::is_same_v<Char, char32_t>,
bool> =
true>
220 template <
bool UseChar8T>
224 template <
typename Char,
size_t Size, if_compatible_
char<Char> = true>
229 template <
typename Visitor>
230 inline constexpr decltype(
auto)
visit(Visitor &&
v)
const;
242 if (
size_t(
n) >=
size_t(
size()))
249 if (
size_t(
n) >=
size_t(
size()))
255 { verify(
pos, 0);
auto r = *
this;
r.advanceData(
pos);
r.setSize(
size() -
pos);
return r; }
257 { verify(
pos,
n);
auto r = *
this;
r.advanceData(
pos);
r.setSize(
n);
return r; }
259 { verify(0,
n);
return sliced(0,
n); }
266 { verify(0,
n); setSize(
n); }
268 { verify(0,
n); setSize(
size() -
n); }
274 {
return qsizetype((m_size >> SizeShift) & SizeMask); }
275 [[nodiscard]]
constexpr const void *
data() const noexcept {
return m_data; }
281#ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED
292 [[nodiscard]]
constexpr QChar back()
const;
293 [[nodiscard]]
constexpr bool empty() const noexcept {
return size() == 0; }
295 {
return size() * charSize(); }
300 [[nodiscard]]
constexpr bool isNull() const noexcept {
return !
m_data; }
301 [[nodiscard]]
constexpr bool isEmpty() const noexcept {
return empty(); }
316#ifndef QT_NO_DEBUG_STREAM
320 [[nodiscard]]
constexpr Tag tag() const noexcept {
return Tag{m_size & TypeMask}; }
321 [[nodiscard]]
constexpr bool isUtf16() const noexcept {
return tag() == Tag::Utf16; }
322 [[nodiscard]]
constexpr bool isUtf8() const noexcept {
return tag() == Tag::Utf8; }
323 [[nodiscard]]
constexpr bool isLatin1() const noexcept {
return tag() == Tag::Latin1; }
324 [[nodiscard]]
constexpr QStringView asStringView()
const
326 [[nodiscard]]
constexpr q_no_char8_t::QUtf8StringView asUtf8StringView()
const
329 [[nodiscard]]
constexpr size_t charSize() const noexcept {
return isUtf16() ? 2 : 1; }
330 constexpr void setSize(
qsizetype sz)
noexcept { m_size = size_t(sz) | tag(); }
331 constexpr void advanceData(
qsizetype delta)
noexcept
347 friend class ::tst_QAnyStringView;
351template <
typename QStringLike, std::enable_if_t<std::disjunction_v<
352 std::is_same<QStringLike, QString>,
353 std::is_same<QStringLike, QByteArray>
constexpr QAnyStringView(std::nullptr_t) noexcept
Constructs a null string view.
constexpr QAnyStringView() noexcept
Constructs a null string view.
constexpr QChar back() const
Returns the last character in the string view.
constexpr QAnyStringView(Char c, Container &&capacity={}) noexcept
constexpr bool isNull() const noexcept
Returns whether this string view is null - that is, whether {data() == nullptr}.
Q_CORE_EXPORT friend QDebug operator<<(QDebug d, QAnyStringView s)
constexpr QAnyStringView sliced(qsizetype pos, qsizetype n) const
constexpr qsizetype size_bytes() const noexcept
Returns the size of this string view, but in bytes, not code-points.
static constexpr bool detects_US_ASCII_at_compile_time
qsizetype size_type
Alias for qsizetype.
constexpr qsizetype size() const noexcept
Returns the size of this string view, in the encoding's code points.
constexpr QAnyStringView(Char ch, QCharContainer &&capacity=QCharContainer()) noexcept
QString toString() const
Returns a deep copy of this string view's data as a QString.
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 constexpr QAnyStringView fromArray(const Char(&string)[Size]) noexcept
constexpr QAnyStringView right(qsizetype n) const
constexpr QAnyStringView(const Char &c) noexcept
static Q_CORE_EXPORT bool equal(QAnyStringView lhs, QAnyStringView rhs) noexcept
constexpr QAnyStringView(Container &&c, QtPrivate::wrapped_t< Container, QByteArray > &&capacity={})
constexpr QAnyStringView(const Char *f, const Char *l)
Constructs a string view on first with length (last - first).
friend bool comparesEqual(const QAnyStringView &lhs, const QAnyStringView &rhs) noexcept
constexpr qsizetype length() const noexcept
Same as size().
constexpr QAnyStringView last(qsizetype n) const
constexpr QAnyStringView sliced(qsizetype pos) const
constexpr QAnyStringView(Container &&c, QtPrivate::wrapped_t< Container, QString > &&capacity={})
const char16_t * m_data_utf16
qptrdiff difference_type
Alias for {std::ptrdiff_t}.
constexpr QChar front() const
Returns the first character in the string view.
constexpr QAnyStringView left(qsizetype n) const
constexpr QAnyStringView(QStringView v) noexcept
constexpr QAnyStringView first(qsizetype n) const
constexpr QAnyStringView(const Char *str, qsizetype len)
Constructs a string view on str with length len.
constexpr QAnyStringView mid(qsizetype pos, qsizetype n=-1) const
constexpr QAnyStringView chopped(qsizetype n) const
constexpr void chop(qsizetype n)
constexpr const void * data() const noexcept
Returns a const pointer to the first character in the string view.
constexpr void truncate(qsizetype n)
constexpr Q_ALWAYS_INLINE QAnyStringView(const Container &c) noexcept
constexpr QAnyStringView(const Pointer &str) noexcept
friend Qt::strong_ordering compareThreeWay(const QAnyStringView &lhs, const QAnyStringView &rhs) noexcept
constexpr QAnyStringView(QBasicUtf8StringView< UseChar8T > v) noexcept
constexpr bool empty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
constexpr decltype(auto) visit(Visitor &&v) const
Calls v with either a QUtf8StringView, QLatin1String, or QStringView, depending on the encoding of th...
\macro QT_RESTRICTED_CAST_FROM_ASCII
\inmodule QtCore \title Classes and helpers for defining comparison operators \keyword qtcompare
Combined button and popup list for selecting options.
IsCompatiblePointer8Helper< q20::remove_cvref_t< Pointer > > IsCompatiblePointer8
constexpr Q_ALWAYS_INLINE std::enable_if_t< sizeof(Char)==sizeof(char16_t), qsizetype > lengthHelperContainer(const Char(&str)[N])
static constexpr qsizetype lengthHelperPointer(const Char *data) noexcept
IsCompatibleChar8TypeHelper< q20::remove_cvref_t< Char > > IsCompatibleChar8Type
typename wrapped< Tag, Result >::type wrapped_t
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION qsizetype qustrlen(const char16_t *str) noexcept
constexpr Qt::strong_ordering compareThreeWay(LeftInt lhs, RightInt rhs) noexcept
constexpr bool is_constant_evaluated() noexcept
QAnyStringView qToAnyStringViewIgnoringNull(const QStringLike &s) noexcept
#define Q_DECLARE_STRONGLY_ORDERED(...)
GLsizei const GLfloat * v
[13]
GLenum GLuint GLintptr GLsizeiptr size
[1]
#define Q_DECLARE_TYPEINFO(TYPE, FLAGS)
\inmodule QtCore \reentrant