summaryrefslogtreecommitdiffstats
path: root/src/corelib/global/qtclasshelpermacros.h
diff options
context:
space:
mode:
authorSona Kurazyan <sona.kurazyan@qt.io>2022-08-12 16:36:54 +0200
committerSona Kurazyan <sona.kurazyan@qt.io>2022-08-19 14:19:24 +0200
commitc201c5aedfcb131d2ac829346812560509904c7d (patch)
tree09f2ed25e0721174429d69da43faf8c79ef61de4 /src/corelib/global/qtclasshelpermacros.h
parent23ecaf897fad6e786d8e833695baecae148c739c (diff)
Extract header qtclasshelpermacros.h
Move the class helper macros from qglobal.h and Q_DECLARE_SHARED from qtypeinfo.h there. Task-number: QTBUG-99313 Change-Id: I8c8b6241a76916176a48c09fbaf4effc87683770 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Diffstat (limited to 'src/corelib/global/qtclasshelpermacros.h')
-rw-r--r--src/corelib/global/qtclasshelpermacros.h144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/corelib/global/qtclasshelpermacros.h b/src/corelib/global/qtclasshelpermacros.h
new file mode 100644
index 0000000000..3c59404910
--- /dev/null
+++ b/src/corelib/global/qtclasshelpermacros.h
@@ -0,0 +1,144 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
+
+#ifndef QTCLASSHELPERMACROS_H
+#define QTCLASSHELPERMACROS_H
+
+#include <QtCore/qtconfigmacros.h>
+
+#if 0
+#pragma qt_class(QtClassHelperMacros)
+#pragma qt_sync_stop_processing
+#endif
+
+QT_BEGIN_NAMESPACE
+
+#if defined(__cplusplus)
+
+/*
+ Some classes do not permit copies to be made of an object. These
+ classes contains a private copy constructor and assignment
+ operator to disable copying (the compiler gives an error message).
+*/
+#define Q_DISABLE_COPY(Class) \
+ Class(const Class &) = delete;\
+ Class &operator=(const Class &) = delete;
+
+#define Q_DISABLE_COPY_MOVE(Class) \
+ Q_DISABLE_COPY(Class) \
+ Class(Class &&) = delete; \
+ Class &operator=(Class &&) = delete;
+
+/*
+ Implementing a move assignment operator using an established
+ technique (move-and-swap, pure swap) is just boilerplate.
+ Here's a couple of *private* macros for convenience.
+
+ To know which one to use:
+
+ * if you don't have a move constructor (*) => use pure swap;
+ * if you have a move constructor, then
+ * if your class holds just memory (no file handles, no user-defined
+ datatypes, etc.) => use pure swap;
+ * use move and swap.
+
+ The preference should always go for the move-and-swap one, as it
+ will deterministically destroy the data previously held in *this,
+ and not "dump" it in the moved-from object (which may then be alive
+ for longer).
+
+ The requirement for either macro is the presence of a member swap(),
+ which any value class that defines its own special member functions
+ should have anyhow.
+
+ (*) Many value classes in Qt do not have move constructors; mostly,
+ the implicitly shared classes using QSharedDataPointer and friends.
+ The reason is mostly historical: those classes require either an
+ out-of-line move constructor, which we could not provide before we
+ made C++11 mandatory (and that we don't like anyhow), or
+ an out-of-line dtor for the Q(E)DSP<Private> member (cf. QPixmap).
+
+ If you can however add a move constructor to a class lacking it,
+ consider doing so, then reevaluate which macro to choose.
+*/
+#define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(Class) \
+ Class &operator=(Class &&other) noexcept { \
+ Class moved(std::move(other)); \
+ swap(moved); \
+ return *this; \
+ }
+
+#define QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_PURE_SWAP(Class) \
+ Class &operator=(Class &&other) noexcept { \
+ swap(other); \
+ return *this; \
+ }
+
+template <typename T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; }
+template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype(ptr.get())
+{ static_assert(noexcept(ptr.get()), "Smart d pointers for Q_DECLARE_PRIVATE must have noexcept get()"); return ptr.get(); }
+
+#define Q_DECLARE_PRIVATE(Class) \
+ inline Class##Private* d_func() noexcept \
+ { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(d_ptr));) } \
+ inline const Class##Private* d_func() const noexcept \
+ { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(d_ptr));) } \
+ friend class Class##Private;
+
+#define Q_DECLARE_PRIVATE_D(Dptr, Class) \
+ inline Class##Private* d_func() noexcept \
+ { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<Class##Private *>(qGetPtrHelper(Dptr));) } \
+ inline const Class##Private* d_func() const noexcept \
+ { Q_CAST_IGNORE_ALIGN(return reinterpret_cast<const Class##Private *>(qGetPtrHelper(Dptr));) } \
+ friend class Class##Private;
+
+#define Q_DECLARE_PUBLIC(Class) \
+ inline Class* q_func() noexcept { return static_cast<Class *>(q_ptr); } \
+ inline const Class* q_func() const noexcept { return static_cast<const Class *>(q_ptr); } \
+ friend class Class;
+
+#define Q_D(Class) Class##Private * const d = d_func()
+#define Q_Q(Class) Class * const q = q_func()
+
+/*
+ Compilers which follow outdated template instantiation rules
+ require a class to have a comparison operator to exist when
+ a QList of this type is instantiated. It's not actually
+ used in the list, though. Hence the dummy implementation.
+ Just in case other code relies on it we better trigger a warning
+ mandating a real implementation.
+*/
+
+#ifdef Q_FULL_TEMPLATE_INSTANTIATION
+# define Q_DUMMY_COMPARISON_OPERATOR(C) \
+ bool operator==(const C&) const { \
+ qWarning(#C"::operator==(const "#C"&) was called"); \
+ return false; \
+ }
+#else
+
+# define Q_DUMMY_COMPARISON_OPERATOR(C)
+#endif
+
+/*
+ Specialize a shared type with:
+
+ Q_DECLARE_SHARED(type)
+
+ where 'type' is the name of the type to specialize. NOTE: shared
+ types must define a member-swap, and be defined in the same
+ namespace as Qt for this to work.
+*/
+
+#define Q_DECLARE_SHARED_IMPL(TYPE, FLAGS) \
+Q_DECLARE_TYPEINFO(TYPE, FLAGS); \
+inline void swap(TYPE &value1, TYPE &value2) \
+ noexcept(noexcept(value1.swap(value2))) \
+{ value1.swap(value2); }
+#define Q_DECLARE_SHARED(TYPE) Q_DECLARE_SHARED_IMPL(TYPE, Q_RELOCATABLE_TYPE)
+
+#endif // __cplusplus
+
+QT_END_NAMESPACE
+
+#endif // QTCLASSHELPERMACROS_H