From 238752495267c3d65c19898dfc8f8d702caffb8b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 10 Sep 2024 14:49:34 -0700 Subject: [PATCH] moc: add a helper function to set member properties There is one minor difference: we now use operator== instead of operator!= now, so some defective types may start working (but may break some other, defective types). Simplifies the emitted code, from case 6: if (_t->sMember != *reinterpret_cast< QString*>(_v)) { _t->sMember = *reinterpret_cast< QString*>(_v); Q_EMIT _t->member5Changed(_t->sMember); } break; case 8: if (_t->sub.m_string != *reinterpret_cast< QString*>(_v)) { _t->sub.m_string = *reinterpret_cast< QString*>(_v); } break; to: case 6: if (QtMocHelpers::setProperty(_t->sMember, *reinterpret_cast(_v))) Q_EMIT _t->member5Changed(_t->sMember); break; case 8: QtMocHelpers::setProperty(_t->sub.m_string, *reinterpret_cast(_v)); break; The second parameter to setProperty() helper is passed as an rvalue reference and forwarded to the assignment, making this ready for move semantics when moc generates code for it. Change-Id: I45ad4a236d38f6c8f994fffd701d4193504d985a Reviewed-by: Ahmad Samir Reviewed-by: Ulf Hermann --- src/corelib/kernel/qtmochelpers.h | 8 +++++ src/tools/moc/generator.cpp | 31 +++++++++---------- .../qmetaproperty/tst_qmetaproperty.cpp | 4 +-- 3 files changed, 25 insertions(+), 18 deletions(-) diff --git a/src/corelib/kernel/qtmochelpers.h b/src/corelib/kernel/qtmochelpers.h index 38c028d5291..a09f0d44014 100644 --- a/src/corelib/kernel/qtmochelpers.h +++ b/src/corelib/kernel/qtmochelpers.h @@ -88,6 +88,14 @@ template inline bool indexOfMethod(void **_a, FuncType f, in return true; } +template inline bool setProperty(Prop &property, Value &&value) +{ + if (property == value) + return false; + property = std::forward(value); + return true; +} + struct NoType {}; template struct ForceCompleteMetaTypes {}; diff --git a/src/tools/moc/generator.cpp b/src/tools/moc/generator.cpp index 84f0d3f45e6..0b8b9c05226 100644 --- a/src/tools/moc/generator.cpp +++ b/src/tools/moc/generator.cpp @@ -1195,23 +1195,22 @@ void Generator::generateStaticMetacall() fprintf(out, " case %d: %s%s(*reinterpret_cast< %s*>(_v)); break;\n", propindex, prefix.constData(), p.write.constData(), p.type.constData()); } else { - fprintf(out, " case %d:\n", propindex); - fprintf(out, " if (%s%s != *reinterpret_cast< %s*>(_v)) {\n", - prefix.constData(), p.member.constData(), p.type.constData()); - fprintf(out, " %s%s = *reinterpret_cast< %s*>(_v);\n", - prefix.constData(), p.member.constData(), p.type.constData()); - if (!p.notify.isEmpty() && p.notifyId > -1) { - const FunctionDef &f = cdef->signalList.at(p.notifyId); - if (f.arguments.size() == 0) - fprintf(out, " Q_EMIT _t->%s();\n", p.notify.constData()); - else if (f.arguments.size() == 1 && f.arguments.at(0).normalizedType == p.type) - fprintf(out, " Q_EMIT _t->%s(%s%s);\n", - p.notify.constData(), prefix.constData(), p.member.constData()); - } else if (!p.notify.isEmpty() && p.notifyId < -1) { - fprintf(out, " Q_EMIT _t->%s();\n", p.notify.constData()); + fprintf(out, " case %d:", propindex); + if (p.notify.isEmpty()) { + fprintf(out, " QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s*>(_v)); break;\n", + prefix.constData(), p.member.constData(), p.type.constData()); + } else { + fprintf(out, "\n if (QtMocHelpers::setProperty(%s%s, *reinterpret_cast<%s*>(_v)))\n", + prefix.constData(), p.member.constData(), p.type.constData()); + fprintf(out, " Q_EMIT _t->%s(", p.notify.constData()); + if (p.notifyId > -1) { + const FunctionDef &f = cdef->signalList.at(p.notifyId); + if (f.arguments.size() == 1 && f.arguments.at(0).normalizedType == p.type) + fprintf(out, "%s%s", prefix.constData(), p.member.constData()); + } + fprintf(out, ");\n"); + fprintf(out, " break;\n"); } - fprintf(out, " }\n"); - fprintf(out, " break;\n"); } } fprintf(out, " default: break;\n"); diff --git a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp index 00cd4c0446f..bde70e32233 100644 --- a/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp +++ b/tests/auto/corelib/kernel/qmetaproperty/tst_qmetaproperty.cpp @@ -16,8 +16,8 @@ struct CustomType QString str; CustomType(const QString &str = QString()) : str(str) {} operator QString() const { return str; } - friend bool operator!=(const CustomType &a, const CustomType &b) - { return a.str != b.str; } + friend bool operator==(const CustomType &a, const CustomType &b) + { return a.str == b.str; } }; Q_DECLARE_METATYPE(CustomType)