File indexing completed on 2026-09-20 09:21:39
0001
0002
0003
0004
0005
0006 #ifndef QAPPLICATIONSTATIC_H
0007 #define QAPPLICATIONSTATIC_H
0008
0009 #include <QtCore/QMutex>
0010 #include <QtCore/qcoreapplication.h>
0011 #include <QtCore/qglobalstatic.h>
0012
0013 #include <new>
0014
0015 #if 0
0016 #pragma qt_class(QApplicationStatic)
0017 #endif
0018
0019 QT_BEGIN_NAMESPACE
0020
0021 namespace QtGlobalStatic {
0022 template <typename QAS> struct ApplicationHolder
0023 {
0024 using Type = typename QAS::QAS_Type;
0025 using PlainType = std::remove_cv_t<Type>;
0026
0027 Q_CONSTINIT static inline struct { alignas(Type) unsigned char data[sizeof(Type)]; } storage = {};
0028 Q_CONSTINIT static inline QBasicAtomicInteger<qint8> guard = { QtGlobalStatic::Uninitialized };
0029 Q_CONSTINIT static inline QBasicMutex mutex {};
0030
0031 static constexpr bool MutexLockIsNoexcept = noexcept(mutex.lock());
0032 static constexpr bool ConstructionIsNoexcept = noexcept(QAS::innerFunction(nullptr));
0033
0034 ApplicationHolder() = default;
0035 Q_DISABLE_COPY_MOVE(ApplicationHolder)
0036 ~ApplicationHolder()
0037 {
0038 if (guard.loadAcquire() == QtGlobalStatic::Initialized) {
0039
0040 guard.storeRelease(QtGlobalStatic::Destroyed);
0041 realPointer()->~PlainType();
0042 }
0043 }
0044
0045 static PlainType *realPointer()
0046 {
0047 return std::launder(reinterpret_cast<PlainType *>(&storage));
0048 }
0049
0050
0051 PlainType *pointer() noexcept(MutexLockIsNoexcept && ConstructionIsNoexcept)
0052 {
0053 if (guard.loadAcquire() == QtGlobalStatic::Initialized)
0054 return realPointer();
0055 QMutexLocker locker(&mutex);
0056 if (guard.loadRelaxed() == QtGlobalStatic::Uninitialized) {
0057 QAS::innerFunction(&storage);
0058 const auto *app = QCoreApplication::instance();
0059 Q_ASSERT_X(app, Q_FUNC_INFO,
0060 "The application static was used without a QCoreApplication instance");
0061 QObject::connect(app, &QObject::destroyed, app, reset, Qt::DirectConnection);
0062 guard.storeRelease(QtGlobalStatic::Initialized);
0063 }
0064 return realPointer();
0065 }
0066
0067 static void reset()
0068 {
0069
0070 QMutexLocker locker(&mutex);
0071 if (guard.loadRelaxed() == QtGlobalStatic::Initialized) {
0072 realPointer()->~PlainType();
0073 guard.storeRelaxed(QtGlobalStatic::Uninitialized);
0074 }
0075 }
0076 };
0077 }
0078
0079 #define Q_APPLICATION_STATIC(TYPE, NAME, ...) \
0080 namespace { struct Q_QAS_ ## NAME { \
0081 typedef TYPE QAS_Type; \
0082 static void innerFunction(void *pointer) \
0083 noexcept(noexcept(std::remove_cv_t<QAS_Type>(__VA_ARGS__))) \
0084 { \
0085 new (pointer) QAS_Type(__VA_ARGS__); \
0086 } \
0087 }; } \
0088 static QGlobalStatic<QtGlobalStatic::ApplicationHolder<Q_QAS_ ## NAME>> NAME;\
0089
0090
0091 QT_END_NAMESPACE
0092
0093 #endif