/*************************************************************************************************** Copyright (C) 2023 The Qt Company Ltd. SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only ***************************************************************************************************/ #pragma once #include "qdotnetexception.h" #ifdef __GNUC__ # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wconversion" #endif #include #ifdef __GNUC__ # pragma GCC diagnostic pop #endif template class QDotNetSafeMethod { using FuncType = QDotNetFunction; using SafeFuncType = QDotNetFunction; public: QDotNetSafeMethod() = default; QDotNetSafeMethod(FuncType func) : func(func) { const QList parameters { QDotNetInbound::Parameter, QDotNetOutbound::Parameter, QDotNetOutbound::Parameter... }; safeFunc = QDotNetAdapter::instance().resolveSafeMethod(func.ptr(), parameters); } bool isValid() const { return func.isValid(); } class SafeReturn : public QDotNetRef { public: SafeReturn(const void *objectRef = nullptr) : QDotNetRef(objectRef) {} SafeReturn(const SafeReturn &cpySrc) : QDotNetRef(cpySrc) {} SafeReturn(SafeReturn &&movSrc) noexcept : QDotNetRef(std::move(movSrc)) {} T value() const { if (!fnValue.isValid()) { fnValue = adapter().resolveInstanceMethod( *this, "get_Value", { QDotNetInbound::Parameter }); } return fnValue(); } QDotNetException exception() const { if (!fnException.isValid()) { fnException = adapter().resolveInstanceMethod( *this, "get_Exception", { QDotNetInbound::Parameter }); } return fnException(); } private: mutable QDotNetFunction fnValue = nullptr; mutable QDotNetFunction fnException = nullptr; }; typename QDotNetInbound::TargetType invoke(QDotNetOutbound::SourceType obj, typename QDotNetOutbound::SourceType... arg) const { SafeReturn safeReturn = safeFunc(obj, arg...).template cast(); QDotNetException exception = safeReturn.exception(); if (!exception.isValid()) return safeReturn.value(); throw exception; } typename QDotNetInbound::TargetType invoke(nullptr_t nullObj, typename QDotNetOutbound::SourceType... arg) const { SafeReturn safeReturn = safeFunc(nullObj, arg...).template cast(); QDotNetException exception = safeReturn.exception(); if (!exception.isValid()) return safeReturn.value(); throw exception; } private: FuncType func = nullptr; SafeFuncType safeFunc = nullptr; }; template class QDotNetSafeMethod { using FuncType = QDotNetFunction; using SafeFuncType = QDotNetFunction; public: QDotNetSafeMethod() = default; QDotNetSafeMethod(FuncType func) : func(func) { const QList parameters { QDotNetInbound::Parameter, QDotNetOutbound::Parameter, QDotNetOutbound::Parameter... }; safeFunc = QDotNetAdapter::instance().resolveSafeMethod(func.ptr(), parameters); } bool isValid() const { return func.isValid(); } class SafeReturn : public QDotNetRef { public: SafeReturn(const void *objectRef = nullptr) : QDotNetRef(objectRef) {} SafeReturn(const SafeReturn &cpySrc) : QDotNetRef(cpySrc) {} SafeReturn(SafeReturn &&movSrc) noexcept : QDotNetRef(std::move(movSrc)) {} QDotNetException exception() const { if (!fnException.isValid()) { fnException = QDotNetAdapter::instance().resolveInstanceMethod( *this, "get_Exception", { QDotNetInbound::Parameter }); } return fnException(); } private: mutable QDotNetFunction fnException = nullptr; }; void invoke(QDotNetOutbound::SourceType obj, typename QDotNetOutbound::SourceType... arg) const { SafeReturn safeReturn = safeFunc(obj, arg...).template cast(); QDotNetException exception = safeReturn.exception(); if (exception.isValid()) throw exception; } void invoke(nullptr_t nullObj, typename QDotNetOutbound::SourceType... arg) const { SafeReturn safeReturn = safeFunc(nullObj, arg...).template cast(); QDotNetException exception = safeReturn.exception(); if (exception.isValid()) throw exception; } private: FuncType func = nullptr; SafeFuncType safeFunc = nullptr; };