diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 24f095a66d..c410c510e6 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -880,20 +880,20 @@ public: return map.contains(k); } - bool insertIfNotContains(Key k, const T *f) + bool insertIfNotContains(Key k, const T &f) { const QWriteLocker locker(&lock); - const T* &fun = map[k]; - if (fun) + if (map.contains(k)) return false; - fun = f; + map.insert(k, f); return true; } const T *function(Key k) const { const QReadLocker locker(&lock); - return map.value(k, nullptr); + auto it = map.find(k); + return it == map.end() ? nullptr : std::addressof(*it); } void remove(int from, int to) @@ -904,10 +904,10 @@ public: } private: mutable QReadWriteLock lock; - QHash map; + QHash map; }; -typedef QMetaTypeFunctionRegistry > +typedef QMetaTypeFunctionRegistry > QMetaTypeConverterRegistry; Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry) @@ -950,7 +950,7 @@ Q_GLOBAL_STATIC(QMetaTypeConverterRegistry, customTypesConversionRegistry) \since 5.2 \internal */ -bool QMetaType::registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to) +bool QMetaType::registerConverterFunction(const ConverterFunction &f, int from, int to) { if (!customTypesConversionRegistry()->insertIfNotContains(qMakePair(from, to), f)) { qWarning("Type conversion already registered from type %s to type %s", @@ -1036,9 +1036,9 @@ bool QMetaType::hasRegisteredDebugStreamOperator() const */ bool QMetaType::convert(const void *from, int fromTypeId, void *to, int toTypeId) { - const QtPrivate::AbstractConverterFunction * const f = + const QMetaType::ConverterFunction * const f = customTypesConversionRegistry()->function(qMakePair(fromTypeId, toTypeId)); - return f && f->convert(f, from, to); + return f && (*f)(from, to); } /*! diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h index cbbb51a3c9..a6c415b268 100644 --- a/src/corelib/kernel/qmetatype.h +++ b/src/corelib/kernel/qmetatype.h @@ -58,6 +58,7 @@ #include #include #include +#include #ifdef Bool #error qmetatype.h must be included before any header file that defines Bool @@ -266,78 +267,6 @@ To convertImplicit(const From& from) return from; } -struct AbstractConverterFunction -{ - typedef bool (*Converter)(const AbstractConverterFunction *, const void *, void*); - explicit AbstractConverterFunction(Converter c = nullptr) - : convert(c) {} - Q_DISABLE_COPY(AbstractConverterFunction) - Converter convert; -}; - -template -struct ConverterMemberFunction : public AbstractConverterFunction -{ - explicit ConverterMemberFunction(To(From::*function)() const) - : AbstractConverterFunction(convert), - m_function(function) {} - ~ConverterMemberFunction(); - static bool convert(const AbstractConverterFunction *_this, const void *in, void *out) - { - const From *f = static_cast(in); - To *t = static_cast(out); - const ConverterMemberFunction *_typedThis = - static_cast(_this); - *t = (f->*_typedThis->m_function)(); - return true; - } - - To(From::* const m_function)() const; -}; - -template -struct ConverterMemberFunctionOk : public AbstractConverterFunction -{ - explicit ConverterMemberFunctionOk(To(From::*function)(bool *) const) - : AbstractConverterFunction(convert), - m_function(function) {} - ~ConverterMemberFunctionOk(); - static bool convert(const AbstractConverterFunction *_this, const void *in, void *out) - { - const From *f = static_cast(in); - To *t = static_cast(out); - bool ok = false; - const ConverterMemberFunctionOk *_typedThis = - static_cast(_this); - *t = (f->*_typedThis->m_function)(&ok); - if (!ok) - *t = To(); - return ok; - } - - To(From::* const m_function)(bool*) const; -}; - -template -struct ConverterFunctor : public AbstractConverterFunction -{ - explicit ConverterFunctor(UnaryFunction function) - : AbstractConverterFunction(convert), - m_function(function) {} - ~ConverterFunctor(); - static bool convert(const AbstractConverterFunction *_this, const void *in, void *out) - { - const From *f = static_cast(in); - To *t = static_cast(out); - const ConverterFunctor *_typedThis = - static_cast(_this); - *t = _typedThis->m_function(*f); - return true; - } - - UnaryFunction m_function; -}; - template struct ValueTypeIsMetaType; template @@ -517,6 +446,9 @@ public: #endif #endif + // type erased converter function + using ConverterFunction = std::function; + // implicit conversion supported like double -> float template static bool registerConverter() @@ -541,8 +473,13 @@ public: const int fromTypeId = qMetaTypeId(); const int toTypeId = qMetaTypeId(); - static const QtPrivate::ConverterMemberFunction f(function); - return registerConverterFunction(&f, fromTypeId, toTypeId); + auto converter = [function](const void *from, void *to) -> bool { + const From *f = static_cast(from); + To *t = static_cast(to); + *t = (f->*function)(); + return true; + }; + return registerConverterFunction(converter, fromTypeId, toTypeId); } // member function as in "double QString::toDouble(bool *ok = nullptr) const" @@ -554,8 +491,16 @@ public: const int fromTypeId = qMetaTypeId(); const int toTypeId = qMetaTypeId(); - static const QtPrivate::ConverterMemberFunctionOk f(function); - return registerConverterFunction(&f, fromTypeId, toTypeId); + auto converter = [function](const void *from, void *to) -> bool { + const From *f = static_cast(from); + To *t = static_cast(to); + bool result = true; + *t = (f->*function)(&result); + if (!result) + *t = To(); + return result; + }; + return registerConverterFunction(converter, fromTypeId, toTypeId); } // functor or function pointer @@ -567,8 +512,13 @@ public: const int fromTypeId = qMetaTypeId(); const int toTypeId = qMetaTypeId(); - static const QtPrivate::ConverterFunctor f(function); - return registerConverterFunction(&f, fromTypeId, toTypeId); + auto converter = [function](const void *from, void *to) -> bool { + const From *f = static_cast(from); + To *t = static_cast(to); + *t = function(*f); + return true; + }; + return registerConverterFunction(converter, fromTypeId, toTypeId); } #endif @@ -607,14 +557,11 @@ public: #ifndef Q_CLANG_QDOC template friend struct QtPrivate::ValueTypeIsMetaType; - template friend struct QtPrivate::ConverterMemberFunction; - template friend struct QtPrivate::ConverterMemberFunctionOk; - template friend struct QtPrivate::ConverterFunctor; template friend struct QtPrivate::AssociativeValueTypeIsMetaType; template friend struct QtPrivate::IsMetaTypePair; template friend struct QtPrivate::MetaTypeSmartPointerHelper; #endif - static bool registerConverterFunction(const QtPrivate::AbstractConverterFunction *f, int from, int to); + static bool registerConverterFunction(const ConverterFunction &f, int from, int to); static void unregisterConverterFunction(int from, int to); private: friend class QVariant; @@ -625,26 +572,6 @@ private: Q_DECLARE_OPERATORS_FOR_FLAGS(QMetaType::TypeFlags) -namespace QtPrivate { - -template -ConverterMemberFunction::~ConverterMemberFunction() -{ - QMetaType::unregisterConverterFunction(qMetaTypeId(), qMetaTypeId()); -} -template -ConverterMemberFunctionOk::~ConverterMemberFunctionOk() -{ - QMetaType::unregisterConverterFunction(qMetaTypeId(), qMetaTypeId()); -} -template -ConverterFunctor::~ConverterFunctor() -{ - QMetaType::unregisterConverterFunction(qMetaTypeId(), qMetaTypeId()); -} - -} - #define QT_METATYPE_PRIVATE_DECLARE_TYPEINFO(C, F) \ } \ Q_DECLARE_TYPEINFO(QtMetaTypePrivate:: C, (F)); \ @@ -1896,10 +1823,7 @@ struct MetaTypeSmartPointerHelper , \ const int toId = QMetaType::QObjectStar; \ if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { \ QtPrivate::QSmartPointerConvertFunctor > o; \ - static const QtPrivate::ConverterFunctor, \ - QObject*, \ - QSmartPointerConvertFunctor > > f(o); \ - return QMetaType::registerConverterFunction(&f, id, toId); \ + return QMetaType::registerConverter, QObject*>(o); \ } \ return true; \ } \ @@ -1984,10 +1908,7 @@ inline bool QtPrivate::IsMetaTypePair::registerConverter(int id) const int toId = qMetaTypeId(); if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { QtMetaTypePrivate::QPairVariantInterfaceConvertFunctor o; - static const QtPrivate::ConverterFunctor > f(o); - return QMetaType::registerConverterFunction(&f, id, toId); + return QMetaType::registerConverter(o); } return true; } @@ -2001,10 +1922,7 @@ namespace QtPrivate { const int toId = qMetaTypeId(); if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { QtMetaTypePrivate::QSequentialIterableConvertFunctor o; - static const QtPrivate::ConverterFunctor > f(o); - return QMetaType::registerConverterFunction(&f, id, toId); + return QMetaType::registerConverter(o); } return true; } @@ -2018,10 +1936,7 @@ namespace QtPrivate { const int toId = qMetaTypeId(); if (!QMetaType::hasRegisteredConverterFunction(id, toId)) { QtMetaTypePrivate::QAssociativeIterableConvertFunctor o; - static const QtPrivate::ConverterFunctor > f(o); - return QMetaType::registerConverterFunction(&f, id, toId); + return QMetaType::registerConverter(o); } return true; }