Long live QT_DEFINE_TAG(_STRUCT)!
We seem to be using more and more of these, and their definition is a bit subtle (need to have an explicit default ctor to avoid {} being an initializer for the type). Port the existing tag structs over to the new macro and add a test, even though we found two users of QT_DEFINE_TAG in QtBase alone, one of which is actually widely used (Disambiguated_t). There are more in other modules. Change-Id: I046bb2b70a2c7e79be2315d91c43e5fd2f0968a0 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> (cherry picked from commit 74a87a329498422db0dea3e469fb84704accbb2b) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
377b4df13b
commit
8a17835180
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include <QtCore/qcompare.h>
|
#include <QtCore/qcompare.h>
|
||||||
|
#include <QtCore/qtclasshelpermacros.h>
|
||||||
#include <QtCore/qtmetamacros.h>
|
#include <QtCore/qtmetamacros.h>
|
||||||
|
|
||||||
#if defined(__OBJC__) && !defined(__cplusplus)
|
#if defined(__OBJC__) && !defined(__cplusplus)
|
||||||
@ -1596,10 +1597,7 @@ namespace Qt {
|
|||||||
};
|
};
|
||||||
inline constexpr Initialization Uninitialized = Initialization::Uninitialized;
|
inline constexpr Initialization Uninitialized = Initialization::Uninitialized;
|
||||||
|
|
||||||
struct Disambiguated_t {
|
inline QT_DEFINE_TAG(Disambiguated);
|
||||||
explicit Disambiguated_t() = default;
|
|
||||||
};
|
|
||||||
inline constexpr Disambiguated_t Disambiguated{};
|
|
||||||
|
|
||||||
enum CoordinateSystem {
|
enum CoordinateSystem {
|
||||||
DeviceCoordinates,
|
DeviceCoordinates,
|
||||||
|
@ -74,6 +74,30 @@ QT_BEGIN_NAMESPACE
|
|||||||
return *this; \
|
return *this; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
These macros can be used to define tag structs in the preferred way (ie.
|
||||||
|
with explicit default ctor).
|
||||||
|
|
||||||
|
The _STRUCT version only defines the tag type, no variable, while the
|
||||||
|
normal macro defines also a variable (and appends _t to the type name to
|
||||||
|
distinguish the two).
|
||||||
|
|
||||||
|
E.g. if we were std, we could use
|
||||||
|
|
||||||
|
QT_DEFINE_TAG(nullopt); // nullopt of type nullopt_t
|
||||||
|
|
||||||
|
The variable will be constexpr by default. If you want to make it static,
|
||||||
|
or inline, or both, prepend those keywords:
|
||||||
|
|
||||||
|
static QT_DEFINE_TAG(MyTag); // static constexpr
|
||||||
|
static inline QT_DEFINE_TAG(MyTag); // static inline constexpr
|
||||||
|
*/
|
||||||
|
#define QT_DEFINE_TAG_STRUCT(TAG) \
|
||||||
|
struct TAG { explicit TAG () = default; }
|
||||||
|
#define QT_DEFINE_TAG(TAG) \
|
||||||
|
constexpr QT_DEFINE_TAG_STRUCT(TAG ## _t) TAG{}
|
||||||
|
|
||||||
|
|
||||||
template <typename T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; }
|
template <typename T> inline T *qGetPtrHelper(T *ptr) noexcept { return ptr; }
|
||||||
template <typename Ptr> inline auto qGetPtrHelper(Ptr &ptr) noexcept -> decltype(ptr.get())
|
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(); }
|
{ static_assert(noexcept(ptr.get()), "Smart d pointers for Q_DECLARE_PRIVATE must have noexcept get()"); return ptr.get(); }
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#define QTDEPRECATIONMARKERS_H
|
#define QTDEPRECATIONMARKERS_H
|
||||||
|
|
||||||
#include <QtCore/qtconfigmacros.h>
|
#include <QtCore/qtconfigmacros.h>
|
||||||
|
#include <QtCore/qtclasshelpermacros.h>
|
||||||
#include <QtCore/qtdeprecationdefinitions.h>
|
#include <QtCore/qtdeprecationdefinitions.h>
|
||||||
#include <QtCore/qtversionchecks.h>
|
#include <QtCore/qtversionchecks.h>
|
||||||
#include <QtCore/qcompilerdetection.h> // for Q_DECL_DEPRECATED
|
#include <QtCore/qcompilerdetection.h> // for Q_DECL_DEPRECATED
|
||||||
@ -309,8 +310,7 @@ QT_BEGIN_NAMESPACE
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
// A tag to help mark stuff deprecated (cf. QStringViewLiteral)
|
// A tag to help mark stuff deprecated (cf. QStringViewLiteral)
|
||||||
namespace QtPrivate {
|
namespace QtPrivate {
|
||||||
enum class Deprecated_t {};
|
inline QT_DEFINE_TAG(Deprecated);
|
||||||
constexpr inline Deprecated_t Deprecated = {};
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -319,11 +319,11 @@ public:
|
|||||||
virtual QEvent *clone() const;
|
virtual QEvent *clone() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct InputEventTag { explicit InputEventTag() = default; };
|
QT_DEFINE_TAG_STRUCT(InputEventTag);
|
||||||
QEvent(Type type, InputEventTag) : QEvent(type) { m_inputEvent = true; }
|
QEvent(Type type, InputEventTag) : QEvent(type) { m_inputEvent = true; }
|
||||||
struct PointerEventTag { explicit PointerEventTag() = default; };
|
QT_DEFINE_TAG_STRUCT(PointerEventTag);
|
||||||
QEvent(Type type, PointerEventTag) : QEvent(type, InputEventTag{}) { m_pointerEvent = true; }
|
QEvent(Type type, PointerEventTag) : QEvent(type, InputEventTag{}) { m_pointerEvent = true; }
|
||||||
struct SinglePointEventTag { explicit SinglePointEventTag() = default; };
|
QT_DEFINE_TAG_STRUCT(SinglePointEventTag);
|
||||||
QEvent(Type type, SinglePointEventTag) : QEvent(type, PointerEventTag{}) { m_singlePointEvent = true; }
|
QEvent(Type type, SinglePointEventTag) : QEvent(type, PointerEventTag{}) { m_singlePointEvent = true; }
|
||||||
quint16 t;
|
quint16 t;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#define QTMETAMACROS_H
|
#define QTMETAMACROS_H
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
|
#include <QtCore/qtclasshelpermacros.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
@ -129,7 +130,7 @@ private: \
|
|||||||
Q_OBJECT_NO_ATTRIBUTES_WARNING \
|
Q_OBJECT_NO_ATTRIBUTES_WARNING \
|
||||||
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
|
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
|
||||||
QT_WARNING_POP \
|
QT_WARNING_POP \
|
||||||
struct QPrivateSignal { explicit QPrivateSignal() = default; }; \
|
QT_DEFINE_TAG_STRUCT(QPrivateSignal); \
|
||||||
QT_ANNOTATE_CLASS(qt_qobject, "")
|
QT_ANNOTATE_CLASS(qt_qobject, "")
|
||||||
|
|
||||||
/* qmake ignore Q_OBJECT */
|
/* qmake ignore Q_OBJECT */
|
||||||
|
@ -75,6 +75,7 @@ private slots:
|
|||||||
void PRImacros();
|
void PRImacros();
|
||||||
void testqToUnderlying();
|
void testqToUnderlying();
|
||||||
void nodiscard();
|
void nodiscard();
|
||||||
|
void tagStructDefinitions();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" { // functions in qglobal.c
|
extern "C" { // functions in qglobal.c
|
||||||
@ -941,6 +942,23 @@ void tst_QGlobal::nodiscard()
|
|||||||
QCOMPARE(t2.get(), 42);
|
QCOMPARE(t2.get(), 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_QGlobal::tagStructDefinitions()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
// predefined:
|
||||||
|
static_assert(std::is_same_v<decltype(QtPrivate::Deprecated), const QtPrivate::Deprecated_t>);
|
||||||
|
[[maybe_unused]] constexpr auto tag = QtPrivate::Deprecated;
|
||||||
|
static_assert(std::is_same_v<decltype(tag), const QtPrivate::Deprecated_t>);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// self-defined:
|
||||||
|
QT_DEFINE_TAG(MyTag);
|
||||||
|
static_assert(std::is_same_v<decltype(MyTag), const MyTag_t>);
|
||||||
|
[[maybe_unused]] constexpr auto tag = MyTag;
|
||||||
|
static_assert(std::is_same_v<decltype(tag), const MyTag_t>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
// Compile-time typeinfo tests
|
// Compile-time typeinfo tests
|
||||||
|
Loading…
x
Reference in New Issue
Block a user