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)