Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qapplicationstatic.h
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// Copyright (C) 2021 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#ifndef QAPPLICATIONSTATIC_H
6#define QAPPLICATIONSTATIC_H
7
8#include <QtCore/QMutex>
9#include <QtCore/qcoreapplication.h>
10#include <QtCore/qglobalstatic.h>
11
12#include <new>
13
15
16namespace QtGlobalStatic {
17template <typename QAS> struct ApplicationHolder
18{
19 using Type = typename QAS::QAS_Type;
20 using PlainType = std::remove_cv_t<Type>;
21
22 Q_CONSTINIT static inline struct { alignas(Type) unsigned char data[sizeof(Type)]; } storage = {};
23 Q_CONSTINIT static inline QBasicAtomicInteger<qint8> guard = { QtGlobalStatic::Uninitialized };
24 Q_CONSTINIT static inline QBasicMutex mutex {};
25
26 static constexpr bool MutexLockIsNoexcept = noexcept(mutex.lock());
27 static constexpr bool ConstructionIsNoexcept = noexcept(QAS::innerFunction(nullptr));
28
29 ApplicationHolder() = default;
30 Q_DISABLE_COPY_MOVE(ApplicationHolder)
32 {
33 if (guard.loadAcquire() == QtGlobalStatic::Initialized) {
34 // No mutex! Up to external code to ensure no race happens.
35 guard.storeRelease(QtGlobalStatic::Destroyed);
36 realPointer()->~PlainType();
37 }
38 }
39
41 {
42 return std::launder(reinterpret_cast<PlainType *>(&storage));
43 }
44
45 // called from QGlobalStatic::instance()
47 {
48 if (guard.loadAcquire() == QtGlobalStatic::Initialized)
49 return realPointer();
50 QMutexLocker locker(&mutex);
51 if (guard.loadRelaxed() == QtGlobalStatic::Uninitialized) {
52 QAS::innerFunction(&storage);
53 const auto *app = QCoreApplication::instance();
55 "The application static was used without a QCoreApplication instance");
58 }
59 return realPointer();
60 }
61
62 static void reset()
63 {
64 // we only synchronize using the mutex here, not the guard
65 QMutexLocker locker(&mutex);
66 realPointer()->~PlainType();
68 }
69};
70} // namespace QtGlobalStatic
71
72#define Q_APPLICATION_STATIC(TYPE, NAME, ...) \
73 namespace { struct Q_QAS_ ## NAME { \
74 typedef TYPE QAS_Type; \
75 static void innerFunction(void *pointer) \
76 noexcept(noexcept(std::remove_cv_t<QAS_Type>(__VA_ARGS__))) \
77 { \
78 new (pointer) QAS_Type(__VA_ARGS__); \
79 } \
80 }; } \
81 static QGlobalStatic<QtGlobalStatic::ApplicationHolder<Q_QAS_ ## NAME>> NAME;\
82
83
85
86#endif // QAPPLICATIONSTATIC_H
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
\inmodule QtCore
Definition qmutex.h:313
\inmodule QtCore
Definition qmutex.h:281
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
void destroyed(QObject *=nullptr)
This signal is emitted immediately before the object obj is destroyed, after any instances of QPointe...
Combined button and popup list for selecting options.
@ DirectConnection
#define Q_FUNC_INFO
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLboolean reset
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
QApplication app(argc, argv)
[0]
static constexpr bool MutexLockIsNoexcept
static Q_CONSTINIT struct QtGlobalStatic::ApplicationHolder::@30 storage
static constexpr bool ConstructionIsNoexcept
static Q_CONSTINIT QBasicAtomicInteger< qint8 > guard
PlainType * pointer() noexcept(MutexLockIsNoexcept &&ConstructionIsNoexcept)
static Q_CONSTINIT QBasicMutex mutex
std::remove_cv_t< Type > PlainType
Definition moc.h:23