diff options
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlprivate.h | 64 |
1 files changed, 56 insertions, 8 deletions
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index 2beeacd20f..4fcfd65c09 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -145,17 +145,57 @@ namespace QQmlPrivate } }; + enum class ConstructionMode + { + None, + Constructor, + Factory + }; + + template<typename T, typename = std::void_t<>> + struct HasSingletonFactory + { + static constexpr bool value = false; + }; + template<typename T> - constexpr bool isConstructible() + struct HasSingletonFactory<T, std::void_t<decltype(T::create( + static_cast<QQmlEngine *>(nullptr), + static_cast<QJSEngine *>(nullptr)))>> { - return std::is_default_constructible<T>::value && std::is_base_of<QObject, T>::value; + static constexpr bool value = std::is_same_v< + decltype(T::create(static_cast<QQmlEngine *>(nullptr), + static_cast<QJSEngine *>(nullptr))), T *>; + }; + + template<typename T> + constexpr ConstructionMode constructionMode() + { + if constexpr (!std::is_base_of<QObject, T>::value) + return ConstructionMode::None; + if constexpr (std::is_default_constructible<T>::value) + return ConstructionMode::Constructor; + if constexpr (HasSingletonFactory<T>::value) + return ConstructionMode::Factory; + + return ConstructionMode::None; } template<typename T> void createInto(void *memory, void *) { new (memory) QQmlElement<T>; } - template<typename T> - QObject *createSingletonInstance(QQmlEngine *, QJSEngine *) { return new T; } + template<typename T, ConstructionMode Mode> + QObject *createSingletonInstance(QQmlEngine *q, QJSEngine *j) + { + Q_UNUSED(q); + Q_UNUSED(j); + if constexpr (Mode == ConstructionMode::Constructor) + return new T; + else if constexpr (Mode == ConstructionMode::Factory) + return T::create(q, j); + else + return nullptr; + } template<typename T> QObject *createParent(QObject *p) { return new T(p); } @@ -165,25 +205,33 @@ namespace QQmlPrivate using CreateParentFunction = QObject *(*)(QObject *); using CreateValueTypeFunction = QVariant (*)(const QJSValue &); - template<typename T, bool Constructible = isConstructible<T>()> + template<typename T, ConstructionMode Mode = constructionMode<T>()> struct Constructors; template<typename T> - struct Constructors<T, true> + struct Constructors<T, ConstructionMode::Constructor> { static constexpr CreateIntoFunction createInto = QQmlPrivate::createInto<T>; static constexpr CreateSingletonFunction createSingletonInstance - = QQmlPrivate::createSingletonInstance<T>; + = QQmlPrivate::createSingletonInstance<T, ConstructionMode::Constructor>; }; template<typename T> - struct Constructors<T, false> + struct Constructors<T, ConstructionMode::None> { static constexpr CreateIntoFunction createInto = nullptr; static constexpr CreateSingletonFunction createSingletonInstance = nullptr; }; + template<typename T> + struct Constructors<T, ConstructionMode::Factory> + { + static constexpr CreateIntoFunction createInto = nullptr; + static constexpr CreateSingletonFunction createSingletonInstance + = QQmlPrivate::createSingletonInstance<T, ConstructionMode::Factory>; + }; + template<typename T, bool IsObject = std::is_base_of<QObject, T>::value, bool IsGadget = QtPrivate::IsGadgetHelper<T>::IsRealGadget> |