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
14#if 0
15#pragma qt_class(QApplicationStatic)
16#endif
17
19
20namespace QtGlobalStatic {
21template <typename QAS> struct ApplicationHolder
22{
23 using Type = typename QAS::QAS_Type;
24 using PlainType = std::remove_cv_t<Type>;
25
26 Q_CONSTINIT static inline struct { alignas(Type) unsigned char data[sizeof(Type)]; } storage = {};
27 Q_CONSTINIT static inline QBasicAtomicInteger<qint8> guard = { QtGlobalStatic::Uninitialized };
28 Q_CONSTINIT static inline QBasicMutex mutex {};
29
30 static constexpr bool MutexLockIsNoexcept = noexcept(mutex.lock());
31 static constexpr bool ConstructionIsNoexcept = noexcept(QAS::innerFunction(nullptr));
32
33 ApplicationHolder() = default;
34 Q_DISABLE_COPY_MOVE(ApplicationHolder)
36 {
37 if (guard.loadAcquire() == QtGlobalStatic::Initialized) {
38 // No mutex! Up to external code to ensure no race happens.
39 guard.storeRelease(QtGlobalStatic::Destroyed);
40 realPointer()->~PlainType();
41 }
42 }
43
45 {
46 return std::launder(reinterpret_cast<PlainType *>(&storage));
47 }
48
49 // called from QGlobalStatic::instance()
51 {
52 if (guard.loadAcquire() == QtGlobalStatic::Initialized)
53 return realPointer();
54 QMutexLocker locker(&mutex);
55 if (guard.loadRelaxed() == QtGlobalStatic::Uninitialized) {
56 QAS::innerFunction(&storage);
57 const auto *app = QCoreApplication::instance();
59 "The application static was used without a QCoreApplication instance");
62 }
63 return realPointer();
64 }
65
66 static void reset()
67 {
68 // we only synchronize using the mutex here, not the guard
69 QMutexLocker locker(&mutex);
70 realPointer()->~PlainType();
72 }
73};
74} // namespace QtGlobalStatic
75
76#define Q_APPLICATION_STATIC(TYPE, NAME, ...) \
77 namespace { struct Q_QAS_ ## NAME { \
78 typedef TYPE QAS_Type; \
79 static void innerFunction(void *pointer) \
80 noexcept(noexcept(std::remove_cv_t<QAS_Type>(__VA_ARGS__))) \
81 { \
82 new (pointer) QAS_Type(__VA_ARGS__); \
83 } \
84 }; } \
85 static QGlobalStatic<QtGlobalStatic::ApplicationHolder<Q_QAS_ ## NAME>> NAME;\
86
87
89
90#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