aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlstringconverters_p.h
diff options
context:
space:
mode:
authorSami Shalayel <sami.shalayel@qt.io>2023-10-20 13:43:18 +0200
committerSami Shalayel <sami.shalayel@qt.io>2024-04-05 17:45:42 +0200
commitaca69f832ab1107c78207138add19224cd877ec2 (patch)
tree69ed74e9e3828ea5f48e3dfe8ba8208821fa564f /src/qml/qml/qqmlstringconverters_p.h
parentd94ec776a743009502260b9e6748d44c2791f151 (diff)
Centralize string parsing for QPoint, QRectF and friends
Put all the string parsing methods into qqmlstringconverters by moving createValueTypeFromNumberString from qquickvaluetypes to qqmlstringconverters. createValueTypeFromNumberString is adapted to be able to parse more value types (like QRectF that has `,` and `x` separators) and split it into the parsing and validating part "isValidNumberString" and into the creation part "valueTypeFromNumberString". Replace duplicate parsing code with "isValidNumberString" and "valueTypeFromNumberString". Task-number: QTBUG-118323 Task-number: QTBUG-118546 Change-Id: I988dc4935ef77072293588ce0918567c7f72f45e Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlstringconverters_p.h')
-rw-r--r--src/qml/qml/qqmlstringconverters_p.h73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/qml/qml/qqmlstringconverters_p.h b/src/qml/qml/qqmlstringconverters_p.h
index 3a82a8ebca..0d220b11fc 100644
--- a/src/qml/qml/qqmlstringconverters_p.h
+++ b/src/qml/qml/qqmlstringconverters_p.h
@@ -43,6 +43,79 @@ namespace QQmlStringConverters
Q_QML_EXPORT QPointF pointFFromString(const QString &, bool *ok = nullptr);
Q_QML_EXPORT QSizeF sizeFFromString(const QString &, bool *ok = nullptr);
Q_QML_EXPORT QRectF rectFFromString(const QString &, bool *ok = nullptr);
+
+ // checks if the string contains a list of doubles separated by separators, like "double1
+ // separators1 double2 separators2 ..." for example.
+ template<int NumParams, char16_t... separators>
+ bool isValidNumberString(const QString &s, std::array<double, NumParams> *numbers = nullptr)
+ {
+ Q_STATIC_ASSERT_X(
+ NumParams == 2 || NumParams == 3 || NumParams == 4 || NumParams == 16,
+ "Unsupported number of params; add an additional case below if necessary.");
+ constexpr std::array<char16_t, NumParams - 1> separatorArray{ separators... };
+ // complain about missing separators when first or last entry is initialized with 0
+ Q_STATIC_ASSERT_X(separatorArray[0] != 0,
+ "Did not specify any separators for isValidNumberString.");
+ Q_STATIC_ASSERT_X(separatorArray[NumParams - 2] != 0,
+ "Did not specify enough separators for isValidNumberString.");
+
+ bool floatOk = true;
+ QStringView view(s);
+ for (qsizetype i = 0; i < NumParams - 1; ++i) {
+ const qsizetype commaIndex = view.indexOf(separatorArray[i]);
+ if (commaIndex == -1)
+ return false;
+ const auto current = view.first(commaIndex).toDouble(&floatOk);
+ if (!floatOk)
+ return false;
+ if (numbers)
+ (*numbers)[i] = current;
+
+ view = view.sliced(commaIndex + 1);
+ }
+ const auto current = view.toDouble(&floatOk);
+ if (!floatOk)
+ return false;
+ if (numbers)
+ (*numbers)[NumParams - 1] = current;
+
+ return true;
+ }
+
+ // Constructs a value type T from the given string that contains NumParams double values
+ // separated by separators, like "double1 separators1 double2 separators2 ..." for example.
+ template<typename T, int NumParams, char16_t... separators>
+ T valueTypeFromNumberString(const QString &s, bool *ok = nullptr)
+ {
+ Q_STATIC_ASSERT_X(
+ NumParams == 2 || NumParams == 3 || NumParams == 4 || NumParams == 16,
+ "Unsupported number of params; add an additional case below if necessary.");
+
+ std::array<double, NumParams> parameters;
+ if (!isValidNumberString<NumParams, separators...>(s, &parameters)) {
+ if (ok)
+ *ok = false;
+ return T{};
+ }
+
+ if (ok)
+ *ok = true;
+
+ if constexpr (NumParams == 2) {
+ return T(parameters[0], parameters[1]);
+ } else if constexpr (NumParams == 3) {
+ return T(parameters[0], parameters[1], parameters[2]);
+ } else if constexpr (NumParams == 4) {
+ return T(parameters[0], parameters[1], parameters[2], parameters[3]);
+ } else if constexpr (NumParams == 16) {
+ return T(parameters[0], parameters[1], parameters[2], parameters[3], parameters[4],
+ parameters[5], parameters[6], parameters[7], parameters[8], parameters[9],
+ parameters[10], parameters[11], parameters[12], parameters[13], parameters[14],
+ parameters[15]);
+ }
+
+ Q_UNREACHABLE_RETURN(T{});
+ }
}
QT_END_NAMESPACE