Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-04 09:21:28

0001 // Copyright (C) 2022 The Qt Company Ltd.
0002 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0003 // Qt-Security score:significant reason:default
0004 
0005 #ifndef QTCLASSHELPERMACROS_H
0006 #define QTCLASSHELPERMACROS_H
0007 
0008 #include <QtCore/qtconfigmacros.h>
0009 
0010 #if 0
0011 #pragma qt_class(QtClassHelperMacros)
0012 #pragma qt_sync_stop_processing
0013 #endif
0014 
0015 QT_BEGIN_NAMESPACE
0016 
0017 #if defined(__cplusplus)
0018 
0019 /*
0020    Some classes do not permit copies to be made of an object. These
0021    classes contains a private copy constructor and assignment
0022    operator to disable copying (the compiler gives an error message).
0023 */
0024 #define Q_DISABLE_COPY(Class) \
0025     Class(const Class &) = delete;\
0026     Class &operator=(const Class &) = delete;
0027 
0028 #define Q_DISABLE_COPY_MOVE(Class) \
0029     Q_DISABLE_COPY(Class) \
0030     Class(Class &&) = delete; \
0031     Class &operator=(Class &&) = delete;
0032 
0033 #define Q_DISABLE_COPY_X(Class, reason) \
0034     Class(const Class &) Q_DECL_EQ_DELETE_X(reason);\
0035     Class &operator=(const Class &) Q_DECL_EQ_DELETE_X(reason);
0036 
0037 #define Q_DISABLE_COPY_MOVE_X(Class, reason) \
0038     Q_DISABLE_COPY_X(Class, reason) \
0039     Class(Class &&) Q_DECL_EQ_DELETE_X(reason); \
0040     Class &operator=(Class &&) Q_DECL_EQ_DELETE_X(reason);
0041 
0042 /*
0043     Implementing a move assignment operator using an established
0044     technique (move-and-swap, pure swap) is just boilerplate.
0045     Here's a couple of *private* macros for convenience.
0046 
0047     To know which one to use:
0048 
0049     * if you don't have a move constructor (*) => use pure swap;
0050     * if you have a move constructor, then
0051       * if your class holds just memory (no file handles, no user-defined
0052         datatypes, etc.) => use pure swap;
0053       * use move and swap.
0054 
0055     The preference should always go for the move-and-swap one, as it
0056     will deterministically destroy the data previously held in *this,
0057     and not "dump" it in the moved-from object (which may then be alive
0058     for longer).
0059 
0060     The requirement for either macro is the presence of a member swap(),
0061     which any value class that defines its own special member functions
0062     should have anyhow.
0063 
0064     (*) Many value classes in Qt do not have move constructors; mostly,
0065     the implicitly shared classes using QSharedDataPointer and friends.
0066     The reason is mostly historical: those classes require either an
0067     out-of-line move constructor, which we could not provide before we
0068     made C++11 mandatory (and that we don't like anyhow), or
0069     an out-of-line dtor for the Q(E)DSP<Private> member (cf. QPixmap).
0070 
0071     If you can however add a move constructor to a class lacking it,
0072     consider doing so, then reevaluate which macro to choose.
0073 */
0074 #define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(Class) \
0075     Class &operator=(Class &&other) noexcept { \
0076         Class moved(std::move(other)); \
0077         swap(moved); \
0078         return *this; \
0079     }
0080 
0081 #define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Class) \
0082     Class &operator=(Class &&other) noexcept { \
0083         swap(other); \
0084         return *this; \
0085     }
0086 
0087 /*
0088     This macro defines the RO5 special member functions (destructor,
0089     copy+move constructors and assignment operators) as defaulted.
0090 
0091     Normally we don't use this macro if we're fine with these functions
0092     to be public; we instead leave a comment in the class declaration,
0093     something like:
0094 
0095     // compiler-generated special member functions are fine!
0096 
0097     In some cases a class may need to redeclare these functions, for
0098     instance if it wants to change their accessibility. Since
0099     defaulting all five is boilerplate, use this macro instead.
0100 
0101     Note that the default constructor is not covered, and this macro
0102     will prevent its automatic generation.
0103 */
0104 
0105 #define QT_DECLARE_RO5_SMF_AS_DEFAULTED(Class) \
0106     ~Class() = default; \
0107     Class(const Class &) = default; \
0108     Class(Class &&) = default; \
0109     Class &operator=(const Class &) = default; \
0110     Class &operator=(Class &&) = default;
0111 
0112 /*
0113     These macros can be used to define tag structs in the preferred way (ie.
0114     with explicit default ctor).
0115 
0116     The _STRUCT version only defines the tag type, no variable, while the
0117     normal macro defines also a variable (and appends _t to the type name to
0118     distinguish the two).
0119 
0120     E.g. if we were std, we could use
0121 
0122        QT_DEFINE_TAG(nullopt); // nullopt of type nullopt_t
0123 
0124     The variable will be constexpr by default. If you want to make it static,
0125     or inline, or both, prepend those keywords:
0126 
0127       static QT_DEFINE_TAG(MyTag); // static constexpr
0128       static inline QT_DEFINE_TAG(MyTag); // static inline constexpr
0129 */
0130 #define QT_DEFINE_TAG_STRUCT(TAG) \
0131     struct TAG { explicit TAG () = default; }
0132 #define QT_DEFINE_TAG(TAG) \
0133     constexpr QT_DEFINE_TAG_STRUCT(TAG ## _t) TAG{}
0134 
0135 
0136 template <typename T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; }
0137 template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype(ptr.get())
0138 { static_assert(noexcept(ptr.get()), "Smart d pointers for Q_DECLARE_PRIVATE must have noexcept get()"); return ptr.get(); }
0139 
0140 class QObject;
0141 class QObjectPrivate;
0142 namespace QtPrivate {
0143     template <typename ObjPrivate> void assertObjectType(QObjectPrivate *d);
0144     inline const QObject *getQObject(const QObjectPrivate *d);
0145 }
0146 
0147 #define Q_DECLARE_PRIVATE(Class) \
0148     inline Class##Private* d_func() noexcept \
0149     { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr));) } \
0150     inline const Class##Private* d_func() const noexcept \
0151     { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));) } \
0152     friend class Class##Private;
0153 
0154 #define Q_DECLARE_PRIVATE_D(Dptr, Class) \
0155     inline Class##Private* d_func() noexcept \
0156     { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr));) } \
0157     inline const Class##Private* d_func() const noexcept \
0158     { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr));) } \
0159     friend class Class##Private;
0160 
0161 #define Q_DECLARE_PUBLIC(Class)                                    \
0162     inline Class* q_func() noexcept { return static_cast<Class *>(q_ptr); } \
0163     inline const Class* q_func() const noexcept { return static_cast<const Class *>(q_ptr); } \
0164     friend class Class; \
0165     friend const QObject *QtPrivate::getQObject(const QObjectPrivate *d); \
0166     template <typename ObjPrivate> friend void QtPrivate::assertObjectType(QObjectPrivate *d);
0167 
0168 #define Q_D(Class) Class##Private * const d = d_func()
0169 #define Q_Q(Class) Class * const q = q_func()
0170 
0171 /*
0172    Specialize a shared type with:
0173 
0174      Q_DECLARE_SHARED(type)
0175 
0176    where 'type' is the name of the type to specialize.  NOTE: shared
0177    types must define a member-swap, and be defined in the same
0178    namespace as Qt for this to work.
0179 
0180    For types defined in a namespace within QT_NAMESPACE, use
0181    Q_DECLARE_SHARED_NS/_EXT instead. The _NS macro needs to be placed
0182    inside the nested namespace:
0183 
0184      namespace ns {
0185      // ~~~ type defined here ~~~
0186      Q_DECLARE_SHARED_NS(ns, type)
0187      }
0188 
0189    while the _NS_EXT macro goes into the QT_NAMESPACE, outside any
0190    nested namespaces:
0191 
0192      namespace ns {
0193      // ~~~ type defined here ~~~
0194      }
0195      Q_DECLARE_SHARED_NS_EXT(ns, type)
0196 
0197    The latter then also works for more deeply-nested namespaces:
0198 
0199      Q_DECLARE_SHARED_NS_EXT(ns1::ns2, type)
0200 
0201    Q_DECLARE_SHARED_NS does, too, if all namespaces were opened in one statement:
0202 
0203      namespace ns1::ns2 {
0204      Q_DECLARE_SHARED_NS(ns1::ns2, type);
0205      }
0206 */
0207 
0208 #define Q_DECLARE_SHARED(TYPE) \
0209 QT_DECLARE_ADL_SWAP(TYPE) \
0210 Q_DECLARE_TYPEINFO(TYPE, Q_RELOCATABLE_TYPE); \
0211 /* end */
0212 
0213 #define Q_DECLARE_SHARED_NS(NS, TYPE) \
0214 QT_DECLARE_ADL_SWAP(TYPE) \
0215 } /* namespace NS */ \
0216 Q_DECLARE_TYPEINFO(NS :: TYPE, Q_RELOCATABLE_TYPE); \
0217 namespace NS { \
0218 /* end */
0219 
0220 #define Q_DECLARE_SHARED_NS_EXT(NS, TYPE) \
0221 namespace NS { \
0222 QT_DECLARE_ADL_SWAP(TYPE) \
0223 } /* namespace NS */ \
0224 Q_DECLARE_TYPEINFO(NS :: TYPE, Q_RELOCATABLE_TYPE); \
0225 /* end */
0226 
0227 #define QT_DECLARE_ADL_SWAP(TYPE) \
0228 inline void swap(TYPE &value1, TYPE &value2) \
0229     noexcept(noexcept(value1.swap(value2))) \
0230 { value1.swap(value2); }
0231 
0232 #endif // __cplusplus
0233 
0234 QT_END_NAMESPACE
0235 
0236 #endif // QTCLASSHELPERMACROS_H