Warning, file /include/QtCore/qrunnable.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004 #ifndef QRUNNABLE_H
0005 #define QRUNNABLE_H
0006
0007 #include <QtCore/qcompilerdetection.h>
0008 #include <QtCore/qfunctionaltools_impl.h>
0009 #include <QtCore/qtclasshelpermacros.h>
0010 #include <QtCore/qtcoreexports.h>
0011
0012 #include <functional>
0013 #include <type_traits>
0014
0015 QT_BEGIN_NAMESPACE
0016
0017 class Q_CORE_EXPORT QRunnable
0018 {
0019 bool m_autoDelete = true;
0020
0021 Q_DISABLE_COPY(QRunnable)
0022 public:
0023 virtual void run() = 0;
0024
0025 constexpr QRunnable() noexcept = default;
0026 virtual ~QRunnable();
0027 #if QT_CORE_REMOVED_SINCE(6, 6)
0028 static QRunnable *create(std::function<void()> functionToRun);
0029 #endif
0030 template <typename Callable>
0031 using if_callable = std::enable_if_t<std::is_invocable_r_v<void, Callable>, bool>;
0032
0033 template <typename Callable, if_callable<Callable> = true>
0034 static QRunnable *create(Callable &&functionToRun);
0035 static QRunnable *create(std::nullptr_t) = delete;
0036
0037 bool autoDelete() const { return m_autoDelete; }
0038 void setAutoDelete(bool autoDelete) { m_autoDelete = autoDelete; }
0039
0040 private:
0041 static Q_DECL_COLD_FUNCTION QRunnable *warnNullCallable();
0042 class QGenericRunnable;
0043 };
0044
0045 class Q_CORE_EXPORT QRunnable::QGenericRunnable : public QRunnable
0046 {
0047
0048 class HelperBase
0049 {
0050 protected:
0051 enum class Op {
0052 Run,
0053 Destroy,
0054 };
0055 using OpFn = void* (*)(Op, HelperBase *, void*);
0056 OpFn fn;
0057 protected:
0058 constexpr explicit HelperBase(OpFn f) noexcept : fn(f) {}
0059 ~HelperBase() = default;
0060 public:
0061 void run() { fn(Op::Run, this, nullptr); }
0062 void destroy() { fn(Op::Destroy, this, nullptr); }
0063 };
0064
0065 template <typename Callable>
0066 class Helper : public HelperBase, private QtPrivate::CompactStorage<Callable>
0067 {
0068 using Storage = QtPrivate::CompactStorage<Callable>;
0069 static void *impl(Op op, HelperBase *that, [[maybe_unused]] void *arg)
0070 {
0071 const auto _this = static_cast<Helper*>(that);
0072 switch (op) {
0073 case Op::Run: _this->object()(); break;
0074 case Op::Destroy: delete _this; break;
0075 }
0076 return nullptr;
0077 }
0078 public:
0079 template <typename UniCallable>
0080 explicit Helper(UniCallable &&functionToRun) noexcept
0081 : HelperBase(&impl),
0082 Storage{std::forward<UniCallable>(functionToRun)}
0083 {
0084 }
0085 };
0086
0087 HelperBase *runHelper;
0088 public:
0089 template <typename Callable, if_callable<Callable> = true>
0090 explicit QGenericRunnable(Callable &&c)
0091 : runHelper(new Helper<std::decay_t<Callable>>(std::forward<Callable>(c)))
0092 {
0093 }
0094 ~QGenericRunnable() override;
0095
0096 void run() override;
0097 };
0098
0099 namespace QtPrivate {
0100
0101 template <typename T>
0102 constexpr inline bool is_function_pointer_v = std::conjunction_v<
0103 std::is_pointer<T>,
0104 std::is_function<std::remove_pointer_t<T>>
0105 >;
0106 template <typename T>
0107 constexpr inline bool is_std_function_v = false;
0108 template <typename T>
0109 constexpr inline bool is_std_function_v<std::function<T>> = true;
0110
0111 }
0112
0113 template <typename Callable, QRunnable::if_callable<Callable>>
0114 QRunnable *QRunnable::create(Callable &&functionToRun)
0115 {
0116 using F = std::decay_t<Callable>;
0117 constexpr bool is_std_function = QtPrivate::is_std_function_v<F>;
0118 constexpr bool is_function_pointer = QtPrivate::is_function_pointer_v<F>;
0119 if constexpr (is_std_function || is_function_pointer) {
0120 bool is_null;
0121 if constexpr (is_std_function) {
0122 is_null = !functionToRun;
0123 } else if constexpr (is_function_pointer) {
0124
0125 const void *functionPtr = reinterpret_cast<void *>(functionToRun);
0126 is_null = !functionPtr;
0127 }
0128 if (is_null)
0129 return warnNullCallable();
0130 }
0131
0132 return new QGenericRunnable(std::forward<Callable>(functionToRun));
0133 }
0134
0135 QT_END_NAMESPACE
0136
0137 #endif