// SPDX-FileCopyrightText: Copyright (C) 2015 swift Project Community / Contributors // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1 //! \file #ifndef SWIFT_MISC_INVOKE_H #define SWIFT_MISC_INVOKE_H #include #include #include #include "misc/integersequence.h" #include "misc/promise.h" #include "misc/typetraits.h" namespace swift::misc::private_ns { //! \cond PRIVATE // Like invoke() but ignores the first argument if callable is not a member function. For uniform calling of // callables with slot semantics. template decltype(auto) invokeSlotImpl(F ptr, T *object, U tuple, std::index_sequence, std::true_type) { Q_UNUSED(tuple); // in case the pack expansion is empty return (object->*ptr)(std::forward>(std::get(tuple))...); } template decltype(auto) invokeSlotImpl(F &&func, T *, U tuple, std::index_sequence, std::false_type) { Q_UNUSED(tuple); // in case the pack expansion is empty return std::forward(func)(std::forward>(std::get(tuple))...); } template decltype(auto) invokeSlot(F &&func, T *object, Ts &&...args) { using seq = MaskSequence, !TIsQPrivateSignal>::value...>; return invokeSlotImpl(std::forward(func), object, std::forward_as_tuple(std::forward(args)...), seq(), std::is_member_pointer>()); } // Like QMetaObject::invokeMethod but the return value is accessed through a QFuture, and extra arguments can be // provided. template auto invokeMethod(T *object, F &&func, Ts &&...args) { const auto invoker = [](auto &&...x) { return private_ns::invokeSlot(std::forward(x)...); }; // NOLINTBEGIN(modernize-avoid-bind) auto method = std::bind(invoker, std::forward(func), object, std::forward(args)...); // NOLINTEND(modernize-avoid-bind) CPromise promise; QMetaObject::invokeMethod( object, [promise, method = std::move(method)]() mutable { promise.setResultFrom(std::move(method)); }); return promise.future(); } //! \endcond } // namespace swift::misc::private_ns #endif // SWIFT_MISC_INVOKE_H