summaryrefslogtreecommitdiffstats
path: root/src/corelib/text/qutf8stringview.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/text/qutf8stringview.h')
-rw-r--r--src/corelib/text/qutf8stringview.h239
1 files changed, 149 insertions, 90 deletions
diff --git a/src/corelib/text/qutf8stringview.h b/src/corelib/text/qutf8stringview.h
index eeab604fa8..fe105e283e 100644
--- a/src/corelib/text/qutf8stringview.h
+++ b/src/corelib/text/qutf8stringview.h
@@ -1,55 +1,24 @@
-/****************************************************************************
-**
-** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
-** Contact: http://www.qt.io/licensing/
-**
-** This file is part of the QtCore module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
+// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz <marc.mutz@kdab.com>
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
#ifndef QUTF8STRINGVIEW_H
#define QUTF8STRINGVIEW_H
+#if 0
+#pragma qt_class(QUtf8StringView)
+#endif
+
#include <QtCore/qstringalgorithms.h>
+#include <QtCore/qstringfwd.h>
#include <QtCore/qarraydata.h> // for QContainerImplHelper
+#include <QtCore/qbytearrayview.h>
+#include <QtCore/qcompare.h>
#include <string>
+#include <string_view>
+#include <QtCore/q20type_traits.h>
QT_BEGIN_NAMESPACE
-template <bool> class QBasicUtf8StringView;
-class QByteArray;
-class QLatin1String;
-
namespace QtPrivate {
template <typename Char>
using IsCompatibleChar8TypeHelper = std::disjunction<
@@ -62,7 +31,7 @@ using IsCompatibleChar8TypeHelper = std::disjunction<
>;
template <typename Char>
using IsCompatibleChar8Type
- = IsCompatibleChar8TypeHelper<std::remove_cv_t<std::remove_reference_t<Char>>>;
+ = IsCompatibleChar8TypeHelper<q20::remove_cvref_t<Char>>;
template <typename Pointer>
struct IsCompatiblePointer8Helper : std::false_type {};
@@ -71,7 +40,7 @@ struct IsCompatiblePointer8Helper<Char*>
: IsCompatibleChar8Type<Char> {};
template <typename Pointer>
using IsCompatiblePointer8
- = IsCompatiblePointer8Helper<std::remove_cv_t<std::remove_reference_t<Pointer>>>;
+ = IsCompatiblePointer8Helper<q20::remove_cvref_t<Pointer>>;
template <typename T, typename Enable = void>
struct IsContainerCompatibleWithQUtf8StringView : std::false_type {};
@@ -98,7 +67,7 @@ struct IsContainerCompatibleWithQUtf8StringView<T, std::enable_if_t<std::conjunc
std::negation<std::is_same<std::decay_t<T>, QByteArray>>,
// This has a compatible value_type, but explicitly a different encoding
- std::negation<std::is_same<std::decay_t<T>, QLatin1String>>,
+ std::negation<std::is_same<std::decay_t<T>, QLatin1StringView>>,
// Don't make an accidental copy constructor
std::negation<std::disjunction<
@@ -117,7 +86,7 @@ struct wrap_char { using type = char; };
} // namespace QtPrivate
-#ifdef Q_CLANG_QDOC
+#ifdef Q_QDOC
#define QBasicUtf8StringView QUtf8StringView
#else
template <bool UseChar8T>
@@ -125,7 +94,7 @@ template <bool UseChar8T>
class QBasicUtf8StringView
{
public:
-#ifndef Q_CLANG_QDOC
+#ifndef Q_QDOC
using storage_type = typename std::conditional<UseChar8T,
QtPrivate::hide_char8_t,
QtPrivate::wrap_char
@@ -196,7 +165,7 @@ public:
constexpr QBasicUtf8StringView(const Char *f, const Char *l)
: QBasicUtf8StringView(f, l - f) {}
-#ifdef Q_CLANG_QDOC
+#ifdef Q_QDOC
template <typename Char, size_t N>
constexpr QBasicUtf8StringView(const Char (&array)[N]) noexcept;
@@ -209,8 +178,9 @@ public:
str ? std::char_traits<std::remove_cv_t<std::remove_pointer_t<Pointer>>>::length(str) : 0) {}
#endif
-#ifdef Q_CLANG_QDOC
+#ifdef Q_QDOC
QBasicUtf8StringView(const QByteArray &str) noexcept;
+ constexpr QBasicUtf8StringView(const storage_type *d, qsizetype n) noexcept {};
#else
template <typename String, if_compatible_qstring_like<String> = true>
QBasicUtf8StringView(const String &str) noexcept
@@ -221,7 +191,7 @@ public:
constexpr QBasicUtf8StringView(const Container &c) noexcept
: QBasicUtf8StringView(std::data(c), lengthHelperContainer(c)) {}
-#ifdef __cpp_char8_t
+#if defined(__cpp_char8_t) && !defined(Q_QDOC)
constexpr QBasicUtf8StringView(QBasicUtf8StringView<!UseChar8T> other)
: QBasicUtf8StringView(other.data(), other.size()) {}
#endif
@@ -233,13 +203,13 @@ public:
[[nodiscard]] inline QString toString() const; // defined in qstring.h
[[nodiscard]] constexpr qsizetype size() const noexcept { return m_size; }
- [[nodiscard]] const_pointer data() const noexcept { return reinterpret_cast<const_pointer>(m_data); }
-#if defined(__cpp_char8_t) || defined(Q_CLANG_QDOC)
+ [[nodiscard]] constexpr const_pointer data() const noexcept { return m_data; }
+#ifdef __cpp_char8_t
[[nodiscard]] const char8_t *utf8() const noexcept { return reinterpret_cast<const char8_t*>(m_data); }
#endif
[[nodiscard]] constexpr storage_type operator[](qsizetype n) const
- { return Q_ASSERT(n >= 0), Q_ASSERT(n < size()), m_data[n]; }
+ { verify(n, 1); return m_data[n]; }
//
// QString API
@@ -270,20 +240,25 @@ public:
}
[[nodiscard]] constexpr QBasicUtf8StringView sliced(qsizetype pos) const
- { verify(pos); return QBasicUtf8StringView{m_data + pos, m_size - pos}; }
+ { verify(pos, 0); return QBasicUtf8StringView{m_data + pos, m_size - pos}; }
[[nodiscard]] constexpr QBasicUtf8StringView sliced(qsizetype pos, qsizetype n) const
{ verify(pos, n); return QBasicUtf8StringView(m_data + pos, n); }
[[nodiscard]] constexpr QBasicUtf8StringView first(qsizetype n) const
- { verify(n); return QBasicUtf8StringView(m_data, n); }
+ { verify(0, n); return sliced(0, n); }
[[nodiscard]] constexpr QBasicUtf8StringView last(qsizetype n) const
- { verify(n); return QBasicUtf8StringView(m_data + m_size - n, n); }
+ { verify(0, n); return sliced(m_size - n, n); }
[[nodiscard]] constexpr QBasicUtf8StringView chopped(qsizetype n) const
- { verify(n); return QBasicUtf8StringView(m_data, m_size - n); }
+ { verify(0, n); return sliced(0, m_size - n); }
constexpr void truncate(qsizetype n)
- { verify(n); m_size = n; }
+ { verify(0, n); m_size = n; }
constexpr void chop(qsizetype n)
- { verify(n); m_size -= n; }
+ { verify(0, n); m_size -= n; }
+
+ [[nodiscard]] inline bool isValidUtf8() const noexcept
+ {
+ return QByteArrayView(reinterpret_cast<const char *>(data()), size()).isValidUtf8();
+ }
//
// STL compatibility API:
@@ -301,6 +276,9 @@ public:
[[nodiscard]] constexpr storage_type front() const { return Q_ASSERT(!empty()), m_data[0]; }
[[nodiscard]] constexpr storage_type back() const { return Q_ASSERT(!empty()), m_data[m_size - 1]; }
+ [[nodiscard]] Q_IMPLICIT operator std::basic_string_view<storage_type>() const noexcept
+ { return std::basic_string_view<storage_type>(data(), size_t(size())); }
+
//
// Qt compatibility API:
//
@@ -309,6 +287,26 @@ public:
[[nodiscard]] constexpr qsizetype length() const noexcept
{ return size(); }
+ [[nodiscard]] int compare(QBasicUtf8StringView other,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept
+ {
+ return QtPrivate::compareStrings(*this, other, cs);
+ }
+
+ [[nodiscard]] int compare(QChar other,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
+ [[nodiscard]] int compare(QStringView other,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
+ [[nodiscard]] int compare(QLatin1StringView other,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
+ [[nodiscard]] int compare(const QByteArray &other,
+ Qt::CaseSensitivity cs = Qt::CaseSensitive) const noexcept;
+
+ [[nodiscard]] bool equal(QChar other) const noexcept;
+ [[nodiscard]] bool equal(QStringView other) const noexcept;
+ [[nodiscard]] bool equal(QLatin1StringView other) const noexcept;
+ [[nodiscard]] bool equal(const QByteArray &other) const noexcept;
+
private:
[[nodiscard]] static inline int compare(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
{
@@ -316,30 +314,96 @@ private:
QBasicUtf8StringView<false>(rhs.data(), rhs.size()));
}
- [[nodiscard]] friend inline bool operator==(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
+ friend bool
+ comparesEqual(const QBasicUtf8StringView &lhs, const QBasicUtf8StringView &rhs) noexcept
{
return lhs.size() == rhs.size()
- && QtPrivate::equalStrings(QBasicUtf8StringView<false>(lhs.data(), lhs.size()),
- QBasicUtf8StringView<false>(rhs.data(), rhs.size()));
+ && QtPrivate::equalStrings(QBasicUtf8StringView<false>(lhs.data(), lhs.size()),
+ QBasicUtf8StringView<false>(rhs.data(), rhs.size()));
+ }
+ friend Qt::strong_ordering
+ compareThreeWay(const QBasicUtf8StringView &lhs, const QBasicUtf8StringView &rhs) noexcept
+ {
+ const int res = QBasicUtf8StringView::compare(lhs, rhs);
+ return Qt::compareThreeWay(res, 0);
}
- [[nodiscard]] friend inline bool operator!=(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
- { return !operator==(lhs, rhs); }
+ Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView)
-#ifdef __cpp_impl_three_way_comparison
- [[nodiscard]] friend inline auto operator<=>(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
- { return QBasicUtf8StringView::compare(lhs, rhs) <=> 0; }
-#else
- [[nodiscard]] friend inline bool operator<=(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
- { return QBasicUtf8StringView::compare(lhs, rhs) <= 0; }
- [[nodiscard]] friend inline bool operator>=(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
- { return QBasicUtf8StringView::compare(lhs, rhs) >= 0; }
- [[nodiscard]] friend inline bool operator<(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
- { return QBasicUtf8StringView::compare(lhs, rhs) < 0; }
- [[nodiscard]] friend inline bool operator>(QBasicUtf8StringView lhs, QBasicUtf8StringView rhs) noexcept
- { return QBasicUtf8StringView::compare(lhs, rhs) > 0; }
-#endif
+ friend bool
+ comparesEqual(const QBasicUtf8StringView &lhs, const QLatin1StringView &rhs) noexcept
+ {
+ return lhs.equal(rhs);
+ }
+ friend Qt::strong_ordering
+ compareThreeWay(const QBasicUtf8StringView &lhs, const QLatin1StringView &rhs) noexcept
+ {
+ const int res = lhs.compare(rhs);
+ return Qt::compareThreeWay(res, 0);
+ }
+ Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QLatin1StringView)
+
+ friend bool
+ comparesEqual(const QBasicUtf8StringView &lhs, const QStringView &rhs) noexcept
+ { return lhs.equal(rhs); }
+ friend Qt::strong_ordering
+ compareThreeWay(const QBasicUtf8StringView &lhs, const QStringView &rhs) noexcept
+ {
+ const int res = lhs.compare(rhs);
+ return Qt::compareThreeWay(res, 0);
+ }
+ Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QStringView)
+
+ friend bool comparesEqual(const QBasicUtf8StringView &lhs, const QChar &rhs) noexcept
+ { return lhs.equal(rhs); }
+ friend Qt::strong_ordering
+ compareThreeWay(const QBasicUtf8StringView &lhs, const QChar &rhs) noexcept
+ {
+ const int res = lhs.compare(rhs);
+ return Qt::compareThreeWay(res, 0);
+ }
+ Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QChar)
+ Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, char16_t)
+
+#if !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
+ friend bool
+ comparesEqual(const QBasicUtf8StringView &lhs, const QByteArrayView &rhs) noexcept
+ {
+ return lhs.size() == rhs.size()
+ && QtPrivate::equalStrings(QBasicUtf8StringView<false>(lhs.data(), lhs.size()),
+ QBasicUtf8StringView<false>(rhs.data(), rhs.size()));
+ }
+ friend Qt::strong_ordering
+ compareThreeWay(const QBasicUtf8StringView &lhs, const QByteArrayView &rhs) noexcept
+ {
+ const int res = QtPrivate::compareStrings(QBasicUtf8StringView<false>(lhs.data(), lhs.size()),
+ QBasicUtf8StringView<false>(rhs.data(), rhs.size()));
+ return Qt::compareThreeWay(res, 0);
+ }
+ Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QByteArrayView, QT_ASCII_CAST_WARN)
- Q_ALWAYS_INLINE constexpr void verify(qsizetype pos, qsizetype n = 0) const
+ friend bool
+ comparesEqual(const QBasicUtf8StringView &lhs, const QByteArray &rhs) noexcept
+ {
+ return lhs.equal(rhs);
+ }
+ friend Qt::strong_ordering
+ compareThreeWay(const QBasicUtf8StringView &lhs, const QByteArray &rhs) noexcept
+ {
+ const int res = lhs.compare(rhs);
+ return Qt::compareThreeWay(res, 0);
+ }
+ Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, QByteArray, QT_ASCII_CAST_WARN)
+
+ friend bool comparesEqual(const QBasicUtf8StringView &lhs, const char *rhs) noexcept
+ { return comparesEqual(lhs, QByteArrayView(rhs)); }
+ friend Qt::strong_ordering
+ compareThreeWay(const QBasicUtf8StringView &lhs, const char *rhs) noexcept
+ { return compareThreeWay(lhs, QByteArrayView(rhs)); }
+ Q_DECLARE_STRONGLY_ORDERED(QBasicUtf8StringView, const char *, QT_ASCII_CAST_WARN)
+#endif // !defined(QT_NO_CAST_FROM_ASCII) && !defined(QT_RESTRICTED_CAST_FROM_ASCII)
+
+ Q_ALWAYS_INLINE constexpr void verify([[maybe_unused]] qsizetype pos = 0,
+ [[maybe_unused]] qsizetype n = 1) const
{
Q_ASSERT(pos >= 0);
Q_ASSERT(pos <= size());
@@ -350,25 +414,20 @@ private:
qsizetype m_size;
};
-#ifdef Q_CLANG_QDOC
+constexpr QByteArrayView::QByteArrayView(QUtf8StringView v) noexcept
+ : QByteArrayView(v.data(), v.size())
+{}
+
+#ifdef Q_QDOC
#undef QBasicUtf8StringView
#else
template <bool UseChar8T>
Q_DECLARE_TYPEINFO_BODY(QBasicUtf8StringView<UseChar8T>, Q_PRIMITIVE_TYPE);
-// ### Qt 7: remove the non-char8_t version of QUtf8StringView
-QT_BEGIN_NO_CHAR8_T_NAMESPACE
-using QUtf8StringView = QBasicUtf8StringView<false>;
-QT_END_NO_CHAR8_T_NAMESPACE
-
-QT_BEGIN_HAS_CHAR8_T_NAMESPACE
-using QUtf8StringView = QBasicUtf8StringView<true>;
-QT_END_HAS_CHAR8_T_NAMESPACE
-#endif // Q_CLANG_QDOC
-
template <typename QStringLike, std::enable_if_t<std::is_same_v<QStringLike, QByteArray>, bool> = true>
[[nodiscard]] inline q_no_char8_t::QUtf8StringView qToUtf8StringViewIgnoringNull(const QStringLike &s) noexcept
-{ return q_no_char8_t::QUtf8StringView(s.data(), s.size()); }
+{ return q_no_char8_t::QUtf8StringView(s.begin(), s.size()); }
+#endif // Q_QDOC
QT_END_NAMESPACE