Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-14 09:02:52

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