1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQUICKDEFERREDPOINTER_P_P_H
5#define QQUICKDEFERREDPOINTER_P_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtCore/qglobal.h>
19#include <QtQml/private/qbipointer_p.h>
20#include <QtQml/private/qqmlcomponent_p.h>
21
22QT_BEGIN_NAMESPACE
23
24class QQuickUntypedDeferredPointer
25{
26 Q_DISABLE_COPY_MOVE(QQuickUntypedDeferredPointer)
27public:
28 QQmlComponentPrivate::DeferredState *deferredState() const
29 {
30 return value.isT1() ? nullptr : &value.asT2()->state;
31 }
32
33 void clearDeferredState()
34 {
35 if (value.isT1())
36 return;
37 value.clearFlag();
38 DeferredState *state = value.asT2();
39 value = state->value;
40 delete state;
41 }
42
43 bool wasExecuted() const { return value.isT1() && value.flag(); }
44 void setExecuted()
45 {
46 Q_ASSERT(value.isT1());
47 value.setFlag();
48 }
49
50 bool isExecuting() const { return value.isT2() && value.flag(); }
51 bool setExecuting(bool b)
52 {
53 if (b) {
54 if (value.isT2()) {
55 // Not our state. Set the flag, but leave it alone.
56 value.setFlag();
57 return false;
58 }
59
60 value = new DeferredState {
61 .state: QQmlComponentPrivate::DeferredState(),
62 .value: value.asT1()
63 };
64 value.setFlag();
65 return true;
66 }
67
68 if (value.isT2()) {
69 value.clearFlag();
70 return true;
71 }
72
73 return false;
74 }
75
76protected:
77 QQuickUntypedDeferredPointer() = default;
78 QQuickUntypedDeferredPointer(void *v) : value(v)
79 {
80 Q_ASSERT(value.isT1());
81 Q_ASSERT(!value.flag());
82 }
83
84 QQuickUntypedDeferredPointer &operator=(void *v)
85 {
86 if (value.isT1())
87 value = v;
88 else
89 value.asT2()->value = v;
90 return *this;
91 }
92
93 ~QQuickUntypedDeferredPointer()
94 {
95 if (value.isT2())
96 delete value.asT2();
97 }
98
99 void *data() const { return value.isT1() ? value.asT1() : value.asT2()->value; }
100
101private:
102 struct DeferredState
103 {
104 QQmlComponentPrivate::DeferredState state;
105 void *value = nullptr;
106 };
107
108 QBiPointer<void, DeferredState> value;
109};
110
111template<typename T>
112class QQuickDeferredPointer : public QQuickUntypedDeferredPointer
113{
114 Q_DISABLE_COPY_MOVE(QQuickDeferredPointer)
115public:
116 Q_NODISCARD_CTOR QQuickDeferredPointer() = default;
117 ~QQuickDeferredPointer() = default;
118
119 Q_NODISCARD_CTOR QQuickDeferredPointer(T *v) : QQuickUntypedDeferredPointer(v) {}
120 QQuickDeferredPointer<T> &operator=(T *o) {
121 QQuickUntypedDeferredPointer::operator=(o);
122 return *this;
123 }
124
125 T *data() const { return static_cast<T *>(QQuickUntypedDeferredPointer::data()); }
126 operator bool() const { return data() != nullptr; }
127 operator T*() const { return data(); }
128 T *operator*() const { return data(); }
129 T *operator->() const { return data(); }
130};
131
132QT_END_NAMESPACE
133
134#endif // QQUICKDEFERREDPOINTER_P_P_H
135

source code of qtdeclarative/src/quicktemplates/qquickdeferredpointer_p_p.h