diff options
Diffstat (limited to 'src/corelib/text/qregularexpression.h')
-rw-r--r-- | src/corelib/text/qregularexpression.h | 219 |
1 files changed, 160 insertions, 59 deletions
diff --git a/src/corelib/text/qregularexpression.h b/src/corelib/text/qregularexpression.h index 6af48f5fb0..2b51b94b15 100644 --- a/src/corelib/text/qregularexpression.h +++ b/src/corelib/text/qregularexpression.h @@ -1,42 +1,7 @@ -/**************************************************************************** -** -** Copyright (C) 2020 Giuseppe D'Angelo <dangelog@gmail.com>. -** Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> -** Contact: https://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 Giuseppe D'Angelo <dangelog@gmail.com>. +// Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> +// Copyright (C) 2021 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QREGULAREXPRESSION_H #define QREGULAREXPRESSION_H @@ -47,17 +12,19 @@ #include <QtCore/qshareddata.h> #include <QtCore/qvariant.h> +#include <iterator> + QT_REQUIRE_CONFIG(regularexpression); QT_BEGIN_NAMESPACE -class QLatin1String; - class QRegularExpressionMatch; class QRegularExpressionMatchIterator; struct QRegularExpressionPrivate; class QRegularExpression; +QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionPrivate, Q_CORE_EXPORT) + Q_CORE_EXPORT size_t qHash(const QRegularExpression &key, size_t seed = 0) noexcept; class Q_CORE_EXPORT QRegularExpression @@ -83,17 +50,18 @@ public: QRegularExpression(); explicit QRegularExpression(const QString &pattern, PatternOptions options = NoPatternOption); - QRegularExpression(const QRegularExpression &re); + QRegularExpression(const QRegularExpression &re) noexcept; + QRegularExpression(QRegularExpression &&re) = default; ~QRegularExpression(); - QRegularExpression &operator=(const QRegularExpression &re); - QRegularExpression &operator=(QRegularExpression &&re) noexcept - { d.swap(re.d); return *this; } + QRegularExpression &operator=(const QRegularExpression &re) noexcept; + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(QRegularExpression) void swap(QRegularExpression &other) noexcept { d.swap(other.d); } QString pattern() const; void setPattern(const QString &pattern); + [[nodiscard]] bool isValid() const; qsizetype patternErrorOffset() const; QString errorString() const; @@ -117,35 +85,57 @@ public: }; Q_DECLARE_FLAGS(MatchOptions, MatchOption) + [[nodiscard]] QRegularExpressionMatch match(const QString &subject, qsizetype offset = 0, MatchType matchType = NormalMatch, MatchOptions matchOptions = NoMatchOption) const; +#if QT_DEPRECATED_SINCE(6, 8) + [[nodiscard]] + QT_DEPRECATED_VERSION_X_6_8("Use matchView instead.") QRegularExpressionMatch match(QStringView subjectView, qsizetype offset = 0, MatchType matchType = NormalMatch, MatchOptions matchOptions = NoMatchOption) const; +#endif + [[nodiscard]] + QRegularExpressionMatch matchView(QStringView subjectView, + qsizetype offset = 0, + MatchType matchType = NormalMatch, + MatchOptions matchOptions = NoMatchOption) const; + + [[nodiscard]] QRegularExpressionMatchIterator globalMatch(const QString &subject, qsizetype offset = 0, MatchType matchType = NormalMatch, MatchOptions matchOptions = NoMatchOption) const; +#if QT_DEPRECATED_SINCE(6, 8) + [[nodiscard]] + QT_DEPRECATED_VERSION_X_6_8("Use globalMatchView instead.") QRegularExpressionMatchIterator globalMatch(QStringView subjectView, qsizetype offset = 0, MatchType matchType = NormalMatch, MatchOptions matchOptions = NoMatchOption) const; +#endif + + [[nodiscard]] + QRegularExpressionMatchIterator globalMatchView(QStringView subjectView, + qsizetype offset = 0, + MatchType matchType = NormalMatch, + MatchOptions matchOptions = NoMatchOption) const; void optimize() const; enum WildcardConversionOption { DefaultWildcardConversion = 0x0, - UnanchoredWildcardConversion = 0x1 + UnanchoredWildcardConversion = 0x1, + NonPathWildcardConversion = 0x2, }; Q_DECLARE_FLAGS(WildcardConversionOptions, WildcardConversionOption) -#if QT_STRINGVIEW_LEVEL < 2 static QString escape(const QString &str) { return escape(qToStringViewIgnoringNull(str)); @@ -160,13 +150,12 @@ public: { return anchoredPattern(qToStringViewIgnoringNull(expression)); } -#endif static QString escape(QStringView str); static QString wildcardToRegularExpression(QStringView str, WildcardConversionOptions options = DefaultWildcardConversion); static QString anchoredPattern(QStringView expression); - static QRegularExpression fromWildcard(QStringView str, Qt::CaseSensitivity cs = Qt::CaseInsensitive, + static QRegularExpression fromWildcard(QStringView pattern, Qt::CaseSensitivity cs = Qt::CaseInsensitive, WildcardConversionOptions options = DefaultWildcardConversion); bool operator==(const QRegularExpression &re) const; @@ -186,6 +175,7 @@ private: Q_DECLARE_SHARED(QRegularExpression) Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::PatternOptions) Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::MatchOptions) +Q_DECLARE_OPERATORS_FOR_FLAGS(QRegularExpression::WildcardConversionOptions) #ifndef QT_NO_DATASTREAM Q_CORE_EXPORT QDataStream &operator<<(QDataStream &out, const QRegularExpression &re); @@ -198,6 +188,7 @@ Q_CORE_EXPORT QDebug operator<<(QDebug debug, QRegularExpression::PatternOptions #endif struct QRegularExpressionMatchPrivate; +QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionMatchPrivate, Q_CORE_EXPORT) class Q_CORE_EXPORT QRegularExpressionMatch { @@ -205,6 +196,7 @@ public: QRegularExpressionMatch(); ~QRegularExpressionMatch(); QRegularExpressionMatch(const QRegularExpressionMatch &match); + QRegularExpressionMatch(QRegularExpressionMatch &&match) = default; QRegularExpressionMatch &operator=(const QRegularExpressionMatch &match); QRegularExpressionMatch &operator=(QRegularExpressionMatch &&match) noexcept { d.swap(match.d); return *this; } @@ -221,16 +213,26 @@ public: int lastCapturedIndex() const; +#if QT_CORE_REMOVED_SINCE(6, 8) + bool hasCaptured(const QString &name) const + { return hasCaptured(qToAnyStringViewIgnoringNull(name)); } + bool hasCaptured(QStringView name) const; +#endif + bool hasCaptured(QAnyStringView name) const; + bool hasCaptured(int nth) const; + QString captured(int nth = 0) const; QStringView capturedView(int nth = 0) const; -#if QT_STRINGVIEW_LEVEL < 2 +#if QT_CORE_REMOVED_SINCE(6, 8) QString captured(const QString &name) const - { return captured(QStringView(name)); } -#endif + { return captured(qToAnyStringViewIgnoringNull(name)); } QString captured(QStringView name) const; QStringView capturedView(QStringView name) const; +#endif + QString captured(QAnyStringView name) const; + QStringView capturedView(QAnyStringView name) const; QStringList capturedTexts() const; @@ -238,18 +240,21 @@ public: qsizetype capturedLength(int nth = 0) const; qsizetype capturedEnd(int nth = 0) const; -#if QT_STRINGVIEW_LEVEL < 2 +#if QT_CORE_REMOVED_SINCE(6, 8) qsizetype capturedStart(const QString &name) const - { return capturedStart(QStringView(name)); } + { return capturedStart(qToAnyStringViewIgnoringNull(name)); } qsizetype capturedLength(const QString &name) const - { return capturedLength(QStringView(name)); } + { return capturedLength(qToAnyStringViewIgnoringNull(name)); } qsizetype capturedEnd(const QString &name) const - { return capturedEnd(QStringView(name)); } -#endif + { return capturedEnd(qToAnyStringViewIgnoringNull(name)); } qsizetype capturedStart(QStringView name) const; qsizetype capturedLength(QStringView name) const; qsizetype capturedEnd(QStringView name) const; +#endif + qsizetype capturedStart(QAnyStringView name) const; + qsizetype capturedLength(QAnyStringView name) const; + qsizetype capturedEnd(QAnyStringView name) const; private: friend class QRegularExpression; @@ -257,7 +262,7 @@ private: friend class QRegularExpressionMatchIterator; QRegularExpressionMatch(QRegularExpressionMatchPrivate &dd); - QSharedDataPointer<QRegularExpressionMatchPrivate> d; + QExplicitlySharedDataPointer<QRegularExpressionMatchPrivate> d; }; Q_DECLARE_SHARED(QRegularExpressionMatch) @@ -266,7 +271,13 @@ Q_DECLARE_SHARED(QRegularExpressionMatch) Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QRegularExpressionMatch &match); #endif +namespace QtPrivate { +class QRegularExpressionMatchIteratorRangeBasedForIterator; +class QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel {}; +} + struct QRegularExpressionMatchIteratorPrivate; +QT_DECLARE_QESDP_SPECIALIZATION_DTOR_WITH_EXPORT(QRegularExpressionMatchIteratorPrivate, Q_CORE_EXPORT) class Q_CORE_EXPORT QRegularExpressionMatchIterator { @@ -274,6 +285,7 @@ public: QRegularExpressionMatchIterator(); ~QRegularExpressionMatchIterator(); QRegularExpressionMatchIterator(const QRegularExpressionMatchIterator &iterator); + QRegularExpressionMatchIterator(QRegularExpressionMatchIterator &&iterator) = default; QRegularExpressionMatchIterator &operator=(const QRegularExpressionMatchIterator &iterator); QRegularExpressionMatchIterator &operator=(QRegularExpressionMatchIterator &&iterator) noexcept { d.swap(iterator.d); return *this; } @@ -291,11 +303,100 @@ public: private: friend class QRegularExpression; + friend Q_CORE_EXPORT QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator); + friend QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel end(const QRegularExpressionMatchIterator &) { return {}; } QRegularExpressionMatchIterator(QRegularExpressionMatchIteratorPrivate &dd); - QSharedDataPointer<QRegularExpressionMatchIteratorPrivate> d; + QExplicitlySharedDataPointer<QRegularExpressionMatchIteratorPrivate> d; }; +namespace QtPrivate { + +// support for range-based for loop +class QRegularExpressionMatchIteratorRangeBasedForIterator +{ +public: + using value_type = QRegularExpressionMatch; + using difference_type = int; + using reference_type = const QRegularExpressionMatch &; + using pointer_type = const QRegularExpressionMatch *; + using iterator_category = std::forward_iterator_tag; + + QRegularExpressionMatchIteratorRangeBasedForIterator() + : m_atEnd(true) + { + } + + explicit QRegularExpressionMatchIteratorRangeBasedForIterator(const QRegularExpressionMatchIterator &iterator) + : m_matchIterator(iterator), + m_currentMatch(), + m_atEnd(false) + { + ++*this; + } + + const QRegularExpressionMatch &operator*() const + { + Q_ASSERT_X(!m_atEnd, Q_FUNC_INFO, "operator* called on an iterator already at the end"); + return m_currentMatch; + } + + QRegularExpressionMatchIteratorRangeBasedForIterator &operator++() + { + Q_ASSERT_X(!m_atEnd, Q_FUNC_INFO, "operator++ called on an iterator already at the end"); + if (m_matchIterator.hasNext()) { + m_currentMatch = m_matchIterator.next(); + } else { + m_currentMatch = QRegularExpressionMatch(); + m_atEnd = true; + } + + return *this; + } + + QRegularExpressionMatchIteratorRangeBasedForIterator operator++(int) + { + QRegularExpressionMatchIteratorRangeBasedForIterator i = *this; + ++*this; + return i; + } + +private: + // [input.iterators] imposes operator== on us. Unfortunately, it's not + // trivial to implement, so just do the bare minimum to satifisfy + // Cpp17EqualityComparable. + friend bool operator==(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs, + const QRegularExpressionMatchIteratorRangeBasedForIterator &rhs) noexcept + { + return (&lhs == &rhs); + } + + friend bool operator!=(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs, + const QRegularExpressionMatchIteratorRangeBasedForIterator &rhs) noexcept + { + return !(lhs == rhs); + } + + // This is what we really use in a range-based for. + friend bool operator==(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs, + QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel) noexcept + { + return lhs.m_atEnd; + } + + friend bool operator!=(const QRegularExpressionMatchIteratorRangeBasedForIterator &lhs, + QRegularExpressionMatchIteratorRangeBasedForIteratorSentinel) noexcept + { + return !lhs.m_atEnd; + } + + QRegularExpressionMatchIterator m_matchIterator; + QRegularExpressionMatch m_currentMatch; + bool m_atEnd; +}; + +} // namespace QtPrivate + Q_DECLARE_SHARED(QRegularExpressionMatchIterator) QT_END_NAMESPACE |