Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Toggle main menu visibility
Loading...
Searching...
No Matches
qtclasshelpermacros.h
Go to the documentation of this file.
1
// Copyright (C) 2022 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
// Qt-Security score:significant reason:default
4
5
#
ifndef
QTCLASSHELPERMACROS_H
6
#
define
QTCLASSHELPERMACROS_H
7
8
#
include
<
QtCore
/
qtconfigmacros
.
h
>
9
10
#
if
0
11
#
pragma
qt_class
(
QtClassHelperMacros
)
12
#
pragma
qt_sync_stop_processing
13
#
endif
14
15
QT_BEGIN_NAMESPACE
16
17
#
if
defined
(
__cplusplus
)
18
19
/*
20
Some classes do not permit copies to be made of an object. These
21
classes contains a private copy constructor and assignment
22
operator to disable copying (the compiler gives an error message).
23
*/
24
#
define
Q_DISABLE_COPY
(
Class
)
25
Class
(
const
Class
&
)
=
delete
;
26
Class
&
operator
=
(
const
Class
&
)
=
delete
;
27
28
#
define
Q_DISABLE_COPY_MOVE
(
Class
)
29
Q_DISABLE_COPY
(
Class
)
30
Class
(
Class
&&
)
=
delete
;
31
Class
&
operator
=
(
Class
&&
)
=
delete
;
32
33
#
define
Q_DISABLE_COPY_X
(
Class
,
reason
)
34
Class
(
const
Class
&
)
Q_DECL_EQ_DELETE_X
(
reason
)
;
35
Class
&
operator
=
(
const
Class
&
)
Q_DECL_EQ_DELETE_X
(
reason
)
;
36
37
#
define
Q_DISABLE_COPY_MOVE_X
(
Class
,
reason
)
38
Q_DISABLE_COPY_X
(
Class
,
reason
)
39
Class
(
Class
&&
)
Q_DECL_EQ_DELETE_X
(
reason
)
;
40
Class
&
operator
=
(
Class
&&
)
Q_DECL_EQ_DELETE_X
(
reason
)
;
41
42
/*
43
Implementing a move assignment operator using an established
44
technique (move-and-swap, pure swap) is just boilerplate.
45
Here's a couple of *private* macros for convenience.
46
47
To know which one to use:
48
49
* if you don't have a move constructor (*) => use pure swap;
50
* if you have a move constructor, then
51
* if your class holds just memory (no file handles, no user-defined
52
datatypes, etc.) => use pure swap;
53
* use move and swap.
54
55
The preference should always go for the move-and-swap one, as it
56
will deterministically destroy the data previously held in *this,
57
and not "dump" it in the moved-from object (which may then be alive
58
for longer).
59
60
The requirement for either macro is the presence of a member swap(),
61
which any value class that defines its own special member functions
62
should have anyhow.
63
64
(*) Many value classes in Qt do not have move constructors; mostly,
65
the implicitly shared classes using QSharedDataPointer and friends.
66
The reason is mostly historical: those classes require either an
67
out-of-line move constructor, which we could not provide before we
68
made C++11 mandatory (and that we don't like anyhow), or
69
an out-of-line dtor for the Q(E)DSP<Private> member (cf. QPixmap).
70
71
If you can however add a move constructor to a class lacking it,
72
consider doing so, then reevaluate which macro to choose.
73
*/
74
#
define
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP
(
Class
)
75
Class
&
operator
=
(
Class
&&
other
)
noexcept
{
76
Class
moved
(
std
::
move
(
other
)
)
;
77
swap
(
moved
)
;
78
return
*
this
;
79
}
80
81
#
define
QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP
(
Class
)
82
Class
&
operator
=
(
Class
&&
other
)
noexcept
{
83
swap
(
other
)
;
84
return
*
this
;
85
}
86
87
/*
88
This macro defines the RO5 special member functions (destructor,
89
copy+move constructors and assignment operators) as defaulted.
90
91
Normally we don't use this macro if we're fine with these functions
92
to be public; we instead leave a comment in the class declaration,
93
something like:
94
95
// compiler-generated special member functions are fine!
96
97
In some cases a class may need to redeclare these functions, for
98
instance if it wants to change their accessibility. Since
99
defaulting all five is boilerplate, use this macro instead.
100
101
Note that the default constructor is not covered, and this macro
102
will prevent its automatic generation.
103
*/
104
105
#
define
QT_DECLARE_RO5_SMF_AS_DEFAULTED
(
Class
)
106
~
Class
(
)
=
default
;
107
Class
(
const
Class
&
)
=
default
;
108
Class
(
Class
&&
)
=
default
;
109
Class
&
operator
=
(
const
Class
&
)
=
default
;
110
Class
&
operator
=
(
Class
&&
)
=
default
;
111
112
/*
113
These macros can be used to define tag structs in the preferred way (ie.
114
with explicit default ctor).
115
116
The _STRUCT version only defines the tag type, no variable, while the
117
normal macro defines also a variable (and appends _t to the type name to
118
distinguish the two).
119
120
E.g. if we were std, we could use
121
122
QT_DEFINE_TAG(nullopt); // nullopt of type nullopt_t
123
124
The variable will be constexpr by default. If you want to make it static,
125
or inline, or both, prepend those keywords:
126
127
static QT_DEFINE_TAG(MyTag); // static constexpr
128
static inline QT_DEFINE_TAG(MyTag); // static inline constexpr
129
*/
130
#
define
QT_DEFINE_TAG_STRUCT
(
TAG
)
131
struct
TAG
{
explicit
TAG
(
)
=
default
;
}
132
#
define
QT_DEFINE_TAG
(
TAG
)
133
constexpr
QT_DEFINE_TAG_STRUCT
(
TAG
##
_t
)
TAG
{
}
134
135
136
template
<
typename
T>
inline
T *qGetPtrHelper(T *ptr)
noexcept
{
return
ptr; }
137
template
<
typename
Ptr>
inline
auto
qGetPtrHelper(Ptr &ptr)
noexcept
->
decltype
(ptr.get())
138
{
static_assert
(
noexcept
(ptr.get()),
"Smart d pointers for Q_DECLARE_PRIVATE must have noexcept get()"
);
return
ptr.get(); }
139
140
class
QObject;
141
class
QObjectPrivate;
142
namespace
QtPrivate
{
143
template
<
typename
ObjPrivate>
void
assertObjectType(QObjectPrivate *d);
144
inline
const
QObject *getQObject(
const
QObjectPrivate *d);
145
}
146
147
#
define
Q_DECLARE_PRIVATE
(
Class
)
148
inline
Class
##
Private
*
d_func
(
)
noexcept
149
{
Q_CAST_IGNORE_ALIGN
(
return
reinterpret_cast
<
Class
##
Private
*
>
(
qGetPtrHelper
(
d_ptr
)
)
;
)
}
150
inline
const
Class
##
Private
*
d_func
(
)
const
noexcept
151
{
Q_CAST_IGNORE_ALIGN
(
return
reinterpret_cast
<
const
Class
##
Private
*
>
(
qGetPtrHelper
(
d_ptr
)
)
;
)
}
152
friend
class
Class
##
Private
;
153
154
#
define
Q_DECLARE_PRIVATE_D
(
Dptr
,
Class
)
155
inline
Class
##
Private
*
d_func
(
)
noexcept
156
{
Q_CAST_IGNORE_ALIGN
(
return
reinterpret_cast
<
Class
##
Private
*
>
(
qGetPtrHelper
(
Dptr
)
)
;
)
}
157
inline
const
Class
##
Private
*
d_func
(
)
const
noexcept
158
{
Q_CAST_IGNORE_ALIGN
(
return
reinterpret_cast
<
const
Class
##
Private
*
>
(
qGetPtrHelper
(
Dptr
)
)
;
)
}
159
friend
class
Class
##
Private
;
160
161
#
define
Q_DECLARE_PUBLIC
(
Class
)
162
inline
Class
*
q_func
(
)
noexcept
{
return
static_cast
<
Class
*
>
(
q_ptr
)
;
}
163
inline
const
Class
*
q_func
(
)
const
noexcept
{
return
static_cast
<
const
Class
*
>
(
q_ptr
)
;
}
164
friend
class
Class
;
165
friend
const
QObject
*
QtPrivate
::
getQObject
(
const
QObjectPrivate
*
d
)
;
166
template
<
typename
ObjPrivate
>
friend
void
QtPrivate
::
assertObjectType
(
QObjectPrivate
*
d
)
;
167
168
#
define
Q_D
(
Class
)
Class
##
Private
*
const
d
=
d_func
(
)
169
#
define
Q_Q
(
Class
)
Class
*
const
q
=
q_func
(
)
170
171
/*
172
Specialize a shared type with:
173
174
Q_DECLARE_SHARED(type)
175
176
where 'type' is the name of the type to specialize. NOTE: shared
177
types must define a member-swap, and be defined in the same
178
namespace as Qt for this to work.
179
180
For types defined in a namespace within QT_NAMESPACE, use
181
Q_DECLARE_SHARED_NS/_EXT instead. The _NS macro needs to be placed
182
inside the nested namespace:
183
184
namespace ns {
185
// ~~~ type defined here ~~~
186
Q_DECLARE_SHARED_NS(ns, type)
187
}
188
189
while the _NS_EXT macro goes into the QT_NAMESPACE, outside any
190
nested namespaces:
191
192
namespace ns {
193
// ~~~ type defined here ~~~
194
}
195
Q_DECLARE_SHARED_NS_EXT(ns, type)
196
197
The latter then also works for more deeply-nested namespaces:
198
199
Q_DECLARE_SHARED_NS_EXT(ns1::ns2, type)
200
201
Q_DECLARE_SHARED_NS does, too, if all namespaces were opened in one statement:
202
203
namespace ns1::ns2 {
204
Q_DECLARE_SHARED_NS(ns1::ns2, type);
205
}
206
*/
207
208
#
define
Q_DECLARE_SHARED
(
TYPE
)
QT_DECLARE_ADL_SWAP
209
(
TYPE
)
Q_DECLARE_TYPEINFO
210
(
TYPE
,
Q_RELOCATABLE_TYPE
)
;
\
211
/* end */
212
213
#
define
Q_DECLARE_SHARED_NS
(
NS
,
TYPE
)
QT_DECLARE_ADL_SWAP
214
(
TYPE
)
\
215
}
/* namespace NS */
Q_DECLARE_TYPEINFO
216
(
NS
::
TYPE
,
Q_RELOCATABLE_TYPE
)
;
namespace
217
NS
{
\
218
/* end */
219
220
#
define
Q_DECLARE_SHARED_NS_EXT
(
NS
,
TYPE
)
namespace
221
NS
{
QT_DECLARE_ADL_SWAP
222
(
TYPE
)
\
223
}
/* namespace NS */
Q_DECLARE_TYPEINFO
224
(
NS
::
TYPE
,
Q_RELOCATABLE_TYPE
)
;
\
225
/* end */
226
227
#
define
QT_DECLARE_ADL_SWAP
(
TYPE
)
inline
228
void
swap
(
TYPE
&
value1
,
TYPE
&
value2
)
229
noexcept
(
noexcept
(
value1
.
swap
(
value2
)
)
)
\
230
{
value1
.
swap
(
value2
)
;
}
231
232
#
endif
// __cplusplus
233
234
QT_END_NAMESPACE
235
236
#
endif
// QTCLASSHELPERMACROS_H
QtPrivate
Definition
qalloc.h:29
qtbase
src
corelib
global
qtclasshelpermacros.h
Generated on
for Qt by
1.18.0