1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtQml module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QFLAGPOINTER_P_H
41#define QFLAGPOINTER_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include <QtCore/qglobal.h>
55
56QT_BEGIN_NAMESPACE
57
58template<typename T>
59class QFlagPointer {
60public:
61 inline QFlagPointer();
62 inline QFlagPointer(T *);
63 inline QFlagPointer(const QFlagPointer<T> &o);
64
65 inline bool isNull() const;
66
67 inline bool flag() const;
68 inline void setFlag();
69 inline void clearFlag();
70 inline void setFlagValue(bool);
71
72 inline bool flag2() const;
73 inline void setFlag2();
74 inline void clearFlag2();
75 inline void setFlag2Value(bool);
76
77 inline QFlagPointer<T> &operator=(const QFlagPointer &o);
78 inline QFlagPointer<T> &operator=(T *);
79
80 inline T *operator->() const;
81 inline T *operator*() const;
82
83 inline T *data() const;
84
85 inline explicit operator bool() const;
86
87private:
88 quintptr ptr_value = 0;
89
90 static const quintptr FlagBit = 0x1;
91 static const quintptr Flag2Bit = 0x2;
92 static const quintptr FlagsMask = FlagBit | Flag2Bit;
93};
94
95template<typename T, typename T2>
96class QBiPointer {
97public:
98 inline QBiPointer();
99 inline QBiPointer(T *);
100 inline QBiPointer(T2 *);
101 inline QBiPointer(const QBiPointer<T, T2> &o);
102
103 inline bool isNull() const;
104 inline bool isT1() const;
105 inline bool isT2() const;
106
107 inline bool flag() const;
108 inline void setFlag();
109 inline void clearFlag();
110 inline void setFlagValue(bool);
111
112 inline QBiPointer<T, T2> &operator=(const QBiPointer<T, T2> &o);
113 inline QBiPointer<T, T2> &operator=(T *);
114 inline QBiPointer<T, T2> &operator=(T2 *);
115
116 inline T *asT1() const;
117 inline T2 *asT2() const;
118
119private:
120 quintptr ptr_value = 0;
121
122 static const quintptr FlagBit = 0x1;
123 static const quintptr Flag2Bit = 0x2;
124 static const quintptr FlagsMask = FlagBit | Flag2Bit;
125};
126
127template<typename T>
128QFlagPointer<T>::QFlagPointer()
129{
130}
131
132template<typename T>
133QFlagPointer<T>::QFlagPointer(T *v)
134: ptr_value(quintptr(v))
135{
136 Q_ASSERT((ptr_value & FlagsMask) == 0);
137}
138
139template<typename T>
140QFlagPointer<T>::QFlagPointer(const QFlagPointer<T> &o)
141: ptr_value(o.ptr_value)
142{
143}
144
145template<typename T>
146bool QFlagPointer<T>::isNull() const
147{
148 return 0 == (ptr_value & (~FlagsMask));
149}
150
151template<typename T>
152bool QFlagPointer<T>::flag() const
153{
154 return ptr_value & FlagBit;
155}
156
157template<typename T>
158void QFlagPointer<T>::setFlag()
159{
160 ptr_value |= FlagBit;
161}
162
163template<typename T>
164void QFlagPointer<T>::clearFlag()
165{
166 ptr_value &= ~FlagBit;
167}
168
169template<typename T>
170void QFlagPointer<T>::setFlagValue(bool v)
171{
172 if (v) setFlag();
173 else clearFlag();
174}
175
176template<typename T>
177bool QFlagPointer<T>::flag2() const
178{
179 return ptr_value & Flag2Bit;
180}
181
182template<typename T>
183void QFlagPointer<T>::setFlag2()
184{
185 ptr_value|= Flag2Bit;
186}
187
188template<typename T>
189void QFlagPointer<T>::clearFlag2()
190{
191 ptr_value &= ~Flag2Bit;
192}
193
194template<typename T>
195void QFlagPointer<T>::setFlag2Value(bool v)
196{
197 if (v) setFlag2();
198 else clearFlag2();
199}
200
201template<typename T>
202QFlagPointer<T> &QFlagPointer<T>::operator=(const QFlagPointer &o)
203{
204 ptr_value = o.ptr_value;
205 return *this;
206}
207
208template<typename T>
209QFlagPointer<T> &QFlagPointer<T>::operator=(T *o)
210{
211 Q_ASSERT((quintptr(o) & FlagsMask) == 0);
212
213 ptr_value = quintptr(o) | (ptr_value & FlagsMask);
214 return *this;
215}
216
217template<typename T>
218T *QFlagPointer<T>::operator->() const
219{
220 return (T *)(ptr_value & ~FlagsMask);
221}
222
223template<typename T>
224T *QFlagPointer<T>::operator*() const
225{
226 return (T *)(ptr_value & ~FlagsMask);
227}
228
229template<typename T>
230T *QFlagPointer<T>::data() const
231{
232 return (T *)(ptr_value & ~FlagsMask);
233}
234
235template<typename T>
236QFlagPointer<T>::operator bool() const
237{
238 return data() != nullptr;
239}
240
241template<typename T, typename T2>
242QBiPointer<T, T2>::QBiPointer()
243{
244}
245
246template<typename T, typename T2>
247QBiPointer<T, T2>::QBiPointer(T *v)
248: ptr_value(quintptr(v))
249{
250 Q_ASSERT((quintptr(v) & FlagsMask) == 0);
251}
252
253template<typename T, typename T2>
254QBiPointer<T, T2>::QBiPointer(T2 *v)
255: ptr_value(quintptr(v) | Flag2Bit)
256{
257 Q_ASSERT((quintptr(v) & FlagsMask) == 0);
258}
259
260template<typename T, typename T2>
261QBiPointer<T, T2>::QBiPointer(const QBiPointer<T, T2> &o)
262: ptr_value(o.ptr_value)
263{
264}
265
266template<typename T, typename T2>
267bool QBiPointer<T, T2>::isNull() const
268{
269 return 0 == (ptr_value & (~FlagsMask));
270}
271
272template<typename T, typename T2>
273bool QBiPointer<T, T2>::isT1() const
274{
275 return !(ptr_value & Flag2Bit);
276}
277
278template<typename T, typename T2>
279bool QBiPointer<T, T2>::isT2() const
280{
281 return ptr_value & Flag2Bit;
282}
283
284template<typename T, typename T2>
285bool QBiPointer<T, T2>::flag() const
286{
287 return ptr_value & FlagBit;
288}
289
290template<typename T, typename T2>
291void QBiPointer<T, T2>::setFlag()
292{
293 ptr_value |= FlagBit;
294}
295
296template<typename T, typename T2>
297void QBiPointer<T, T2>::clearFlag()
298{
299 ptr_value &= ~FlagBit;
300}
301
302template<typename T, typename T2>
303void QBiPointer<T, T2>::setFlagValue(bool v)
304{
305 if (v) setFlag();
306 else clearFlag();
307}
308
309template<typename T, typename T2>
310QBiPointer<T, T2> &QBiPointer<T, T2>::operator=(const QBiPointer<T, T2> &o)
311{
312 ptr_value = o.ptr_value;
313 return *this;
314}
315
316template<typename T, typename T2>
317QBiPointer<T, T2> &QBiPointer<T, T2>::operator=(T *o)
318{
319 Q_ASSERT((quintptr(o) & FlagsMask) == 0);
320
321 ptr_value = quintptr(o) | (ptr_value & FlagBit);
322 return *this;
323}
324
325template<typename T, typename T2>
326QBiPointer<T, T2> &QBiPointer<T, T2>::operator=(T2 *o)
327{
328 Q_ASSERT((quintptr(o) & FlagsMask) == 0);
329
330 ptr_value = quintptr(o) | (ptr_value & FlagBit) | Flag2Bit;
331 return *this;
332}
333
334template<typename T, typename T2>
335T *QBiPointer<T, T2>::asT1() const
336{
337 Q_ASSERT(isT1());
338 return (T *)(ptr_value & ~FlagsMask);
339}
340
341template<typename T, typename T2>
342T2 *QBiPointer<T, T2>::asT2() const
343{
344 Q_ASSERT(isT2());
345 return (T2 *)(ptr_value & ~FlagsMask);
346}
347
348QT_END_NAMESPACE
349
350#endif // QFLAGPOINTER_P_H
351