From 812a0d3125cb89e340c59aa92cdc946862fb009d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Sun, 7 Aug 2022 22:18:38 +0200 Subject: [PATCH] QAnyStringView: construct from any T implicitly convertible to QString/QByteArray This includes QDBusReply, QProperty, and QStringBuilder expressions. The new constructor subsumes the QStringBuilder case without requiring jumping though hoops to delay the definition of the ctor the way we had to for the explicit QStringBuilder constructor, so remove the explicit QStringBuilder one again. [ChangeLog][QtCore][QAnyStringView] Can now be constructed from anything that implicitly converts to either QString or QByteArray. Fixes: QTBUG-105389 Change-Id: I0e584dd3e20d591381609a3329ef47cec7356ecc Reviewed-by: Oliver Wolff Reviewed-by: Fabian Kosmale Reviewed-by: Qt CI Bot Reviewed-by: Sona Kurazyan --- src/corelib/kernel/qobject.cpp | 2 +- src/corelib/text/qanystringview.h | 41 +++++++++++++++---- src/corelib/text/qstringbuilder.h | 9 ---- .../qanystringview/tst_qanystringview.cpp | 10 +++++ 4 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index ac5e839eb2e..f2124678f07 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -1279,7 +1279,7 @@ void QObject::setObjectName(QAnyStringView name) d->extraData->objectName.removeBindingUnlessInWrapper(); - if (d->extraData->objectName.value() != name) { + if (d->extraData->objectName != name) { d->extraData->objectName.setValueBypassingBindings(name.toString()); d->extraData->objectName.notify(); // also emits a signal } diff --git a/src/corelib/text/qanystringview.h b/src/corelib/text/qanystringview.h index 0cd97fd54e2..36262e28e16 100644 --- a/src/corelib/text/qanystringview.h +++ b/src/corelib/text/qanystringview.h @@ -1,3 +1,4 @@ +// Copyright (C) 2022 The Qt Company Ltd. // Copyright (C) 2020 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Marc Mutz // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #ifndef QANYSTRINGVIEW_H @@ -9,14 +10,22 @@ #ifdef __cpp_impl_three_way_comparison #include #endif +#include #include class tst_QAnyStringView; QT_BEGIN_NAMESPACE -template class QStringBuilder; -template struct QConcatenable; +namespace QtPrivate { + +template +struct wrapped { using type = Result; }; + +template +using wrapped_t = typename wrapped::type; + +} // namespace QtPrivate class QAnyStringView { @@ -43,6 +52,19 @@ private: QtPrivate::IsContainerCompatibleWithQUtf8StringView >, bool>; + template + using if_convertible_to = std::enable_if_t, QAnyStringView>, // don't make a copy/move ctor + std::is_pointer>, // const char*, etc + std::is_same, QByteArray>, + std::is_same, QString> + >>, + // this is what we're really after: + std::is_convertible + >, bool>; + // confirm we don't make an accidental copy constructor: static_assert(QtPrivate::IsContainerCompatibleWithQStringView::value == false); static_assert(QtPrivate::IsContainerCompatibleWithQUtf8StringView::value == false); @@ -155,15 +177,20 @@ public: inline QAnyStringView(const QString &str) noexcept; inline constexpr QAnyStringView(QLatin1StringView str) noexcept; - // defined in qstringbuilder.h - template - inline QAnyStringView(const QStringBuilder &expr, - typename QConcatenable>::ConvertTo &&capacity = {}); - template = true> constexpr QAnyStringView(const Container &c) noexcept : QAnyStringView(std::data(c), lengthHelperContainer(c)) {} + template = true> + constexpr QAnyStringView(Container &&c, QtPrivate::wrapped_t &&capacity = {}) + //noexcept(std::is_nothrow_constructible_v) + : QAnyStringView(capacity = std::forward(c)) {} + + template = true> + constexpr QAnyStringView(Container &&c, QtPrivate::wrapped_t &&capacity = {}) + //noexcept(std::is_nothrow_constructible_v) + : QAnyStringView(capacity = std::forward(c)) {} + template = true> constexpr QAnyStringView(const Char &c) noexcept : QAnyStringView{&c, 1} {} diff --git a/src/corelib/text/qstringbuilder.h b/src/corelib/text/qstringbuilder.h index f3958114dc2..4318e219edf 100644 --- a/src/corelib/text/qstringbuilder.h +++ b/src/corelib/text/qstringbuilder.h @@ -452,15 +452,6 @@ QString &operator+=(QString &a, const QStringBuilder &b) return a; } -// -// inline QAnyStringView members requiring QStringBuilder: -// - -template -QAnyStringView::QAnyStringView(const QStringBuilder &expr, - typename QConcatenable>::ConvertTo &&capacity) - : QAnyStringView(capacity = expr) {} - QT_END_NAMESPACE #endif // QSTRINGBUILDER_H diff --git a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp index 4433b8efbcd..be34d9aa8cd 100644 --- a/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp +++ b/tests/auto/corelib/text/qanystringview/tst_qanystringview.cpp @@ -59,6 +59,16 @@ static_assert(CanConvert); static_assert(CanConvert); static_assert(CanConvert); +template +struct ImplicitlyConvertibleTo +{ + operator T() const; +}; + +static_assert(CanConvert>); +static_assert(CanConvert>); +static_assert(!CanConvert>); + // QAnyStringView qchar_does_not_compile() { return QAnyStringView(QChar('a')); } // QAnyStringView qlatin1string_does_not_compile() { return QAnyStringView(QLatin1String("a")); } // QAnyStringView const_char_star_does_not_compile() { return QAnyStringView("a"); }