diff options
Diffstat (limited to 'src/quicktemplates/qquickdeferredpointer_p_p.h')
-rw-r--r-- | src/quicktemplates/qquickdeferredpointer_p_p.h | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/src/quicktemplates/qquickdeferredpointer_p_p.h b/src/quicktemplates/qquickdeferredpointer_p_p.h new file mode 100644 index 0000000000..e1fa85e2ee --- /dev/null +++ b/src/quicktemplates/qquickdeferredpointer_p_p.h @@ -0,0 +1,134 @@ +// Copyright (C) 2017 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 + +#ifndef QQUICKDEFERREDPOINTER_P_P_H +#define QQUICKDEFERREDPOINTER_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/qglobal.h> +#include <QtQml/private/qbipointer_p.h> +#include <QtQml/private/qqmlcomponent_p.h> + +QT_BEGIN_NAMESPACE + +class QQuickUntypedDeferredPointer +{ + Q_DISABLE_COPY_MOVE(QQuickUntypedDeferredPointer) +public: + QQmlComponentPrivate::DeferredState *deferredState() const + { + return value.isT1() ? nullptr : &value.asT2()->state; + } + + void clearDeferredState() + { + if (value.isT1()) + return; + value.clearFlag(); + DeferredState *state = value.asT2(); + value = state->value; + delete state; + } + + bool wasExecuted() const { return value.isT1() && value.flag(); } + void setExecuted() + { + Q_ASSERT(value.isT1()); + value.setFlag(); + } + + bool isExecuting() const { return value.isT2() && value.flag(); } + bool setExecuting(bool b) + { + if (b) { + if (value.isT2()) { + // Not our state. Set the flag, but leave it alone. + value.setFlag(); + return false; + } + + value = new DeferredState { + QQmlComponentPrivate::DeferredState(), + value.asT1() + }; + value.setFlag(); + return true; + } + + if (value.isT2()) { + value.clearFlag(); + return true; + } + + return false; + } + +protected: + QQuickUntypedDeferredPointer() = default; + QQuickUntypedDeferredPointer(void *v) : value(v) + { + Q_ASSERT(value.isT1()); + Q_ASSERT(!value.flag()); + } + + QQuickUntypedDeferredPointer &operator=(void *v) + { + if (value.isT1()) + value = v; + else + value.asT2()->value = v; + return *this; + } + + ~QQuickUntypedDeferredPointer() + { + if (value.isT2()) + delete value.asT2(); + } + + void *data() const { return value.isT1() ? value.asT1() : value.asT2()->value; } + +private: + struct DeferredState + { + QQmlComponentPrivate::DeferredState state; + void *value = nullptr; + }; + + QBiPointer<void, DeferredState> value; +}; + +template<typename T> +class QQuickDeferredPointer : public QQuickUntypedDeferredPointer +{ + Q_DISABLE_COPY_MOVE(QQuickDeferredPointer) +public: + Q_NODISCARD_CTOR QQuickDeferredPointer() = default; + ~QQuickDeferredPointer() = default; + + Q_NODISCARD_CTOR QQuickDeferredPointer(T *v) : QQuickUntypedDeferredPointer(v) {} + QQuickDeferredPointer<T> &operator=(T *o) { + QQuickUntypedDeferredPointer::operator=(o); + return *this; + } + + T *data() const { return static_cast<T *>(QQuickUntypedDeferredPointer::data()); } + operator bool() const { return data() != nullptr; } + operator T*() const { return data(); } + T *operator*() const { return data(); } + T *operator->() const { return data(); } +}; + +QT_END_NAMESPACE + +#endif // QQUICKDEFERREDPOINTER_P_P_H |