Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:07:39

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 /*
0033     Implementing a move assignment operator using an established
0034     technique (move-and-swap, pure swap) is just boilerplate.
0035     Here's a couple of *private* macros for convenience.
0036 
0037     To know which one to use:
0038 
0039     * if you don't have a move constructor (*) => use pure swap;
0040     * if you have a move constructor, then
0041       * if your class holds just memory (no file handles, no user-defined
0042         datatypes, etc.) => use pure swap;
0043       * use move and swap.
0044 
0045     The preference should always go for the move-and-swap one, as it
0046     will deterministically destroy the data previously held in *this,
0047     and not "dump" it in the moved-from object (which may then be alive
0048     for longer).
0049 
0050     The requirement for either macro is the presence of a member swap(),
0051     which any value class that defines its own special member functions
0052     should have anyhow.
0053 
0054     (*) Many value classes in Qt do not have move constructors; mostly,
0055     the implicitly shared classes using QSharedDataPointer and friends.
0056     The reason is mostly historical: those classes require either an
0057     out-of-line move constructor, which we could not provide before we
0058     made C++11 mandatory (and that we don't like anyhow), or
0059     an out-of-line dtor for the Q(E)DSP<Private> member (cf. QPixmap).
0060 
0061     If you can however add a move constructor to a class lacking it,
0062     consider doing so, then reevaluate which macro to choose.
0063 */
0064 #define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(Class) \
0065     Class &operator=(Class &&other) noexcept { \
0066         Class moved(std::move(other)); \
0067         swap(moved); \
0068         return *this; \
0069     }
0070 
0071 #define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Class) \
0072     Class &operator=(Class &&other) noexcept { \
0073         swap(other); \
0074         return *this; \
0075     }
0076 
0077 template <typename T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; }
0078 template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype(ptr.get())
0079 { static_assert(noexcept(ptr.get()), "Smart d pointers for Q_DECLARE_PRIVATE must have noexcept get()"); return ptr.get(); }
0080 
0081 class QObject;
0082 class QObjectPrivate;
0083 namespace QtPrivate {
0084     template <typename ObjPrivate> void assertObjectType(QObjectPrivate *d);
0085     inline const QObject *getQObject(const QObjectPrivate *d);
0086 }
0087 
0088 #define Q_DECLARE_PRIVATE(Class) \
0089     inline Class##Private* d_func() noexcept \
0090     { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr));) } \
0091     inline const Class##Private* d_func() const noexcept \
0092     { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));) } \
0093     friend class Class##Private;
0094 
0095 #define Q_DECLARE_PRIVATE_D(Dptr, Class) \
0096     inline Class##Private* d_func() noexcept \
0097     { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr));) } \
0098     inline const Class##Private* d_func() const noexcept \
0099     { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr));) } \
0100     friend class Class##Private;
0101 
0102 #define Q_DECLARE_PUBLIC(Class)                                    \
0103     inline Class* q_func() noexcept { return static_cast<Class *>(q_ptr); } \
0104     inline const Class* q_func() const noexcept { return static_cast<const Class *>(q_ptr); } \
0105     friend class Class; \
0106     friend const QObject *QtPrivate::getQObject(const QObjectPrivate *d); \
0107     template <typename ObjPrivate> friend void QtPrivate::assertObjectType(QObjectPrivate *d);
0108 
0109 #define Q_D(Class) Class##Private * const d = d_func()
0110 #define Q_Q(Class) Class * const q = q_func()
0111 
0112 /*
0113    Specialize a shared type with:
0114 
0115      Q_DECLARE_SHARED(type)
0116 
0117    where 'type' is the name of the type to specialize.  NOTE: shared
0118    types must define a member-swap, and be defined in the same
0119    namespace as Qt for this to work.
0120 */
0121 
0122 #define Q_DECLARE_SHARED(TYPE) \
0123 Q_DECLARE_TYPEINFO(TYPE, Q_RELOCATABLE_TYPE); \
0124 inline void swap(TYPE &value1, TYPE &value2) \
0125     noexcept(noexcept(value1.swap(value2))) \
0126 { value1.swap(value2); }
0127 
0128 #endif // __cplusplus
0129 
0130 QT_END_NAMESPACE
0131 
0132 #endif // QTCLASSHELPERMACROS_H