QGlobalStatic: don't use a std::aligned_union if we can be a union
Simplifies further the code with C++11 unrestricted unions. Pick-to: 6.3 Task-number: QTBUG-99122 Change-Id: Ib42b3adc93bf4d43bd55fffd16c0b6677441bf55 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
parent
e832a805c1
commit
c54fb03446
@ -57,15 +57,17 @@ enum GuardValues {
|
|||||||
Initializing = 1
|
Initializing = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename QGS> struct Holder
|
template <typename QGS> union Holder
|
||||||
{
|
{
|
||||||
using Type = typename QGS::QGS_Type;
|
using Type = typename QGS::QGS_Type;
|
||||||
using PlainType = std::remove_cv_t<Type>;
|
using PlainType = std::remove_cv_t<Type>;
|
||||||
|
|
||||||
static constexpr bool ConstructionIsNoexcept = noexcept(QGS::innerFunction(nullptr));
|
static constexpr bool ConstructionIsNoexcept = noexcept(QGS::innerFunction(nullptr));
|
||||||
std::aligned_union_t<1, PlainType> storage;
|
|
||||||
static inline QBasicAtomicInteger<qint8> guard = { QtGlobalStatic::Uninitialized };
|
static inline QBasicAtomicInteger<qint8> guard = { QtGlobalStatic::Uninitialized };
|
||||||
|
|
||||||
|
// union's sole member
|
||||||
|
PlainType storage;
|
||||||
|
|
||||||
Holder() noexcept(ConstructionIsNoexcept)
|
Holder() noexcept(ConstructionIsNoexcept)
|
||||||
{
|
{
|
||||||
QGS::innerFunction(pointer());
|
QGS::innerFunction(pointer());
|
||||||
@ -81,7 +83,7 @@ template <typename QGS> struct Holder
|
|||||||
|
|
||||||
PlainType *pointer() noexcept
|
PlainType *pointer() noexcept
|
||||||
{
|
{
|
||||||
return reinterpret_cast<PlainType *>(&storage);
|
return &storage;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DISABLE_COPY_MOVE(Holder)
|
Q_DISABLE_COPY_MOVE(Holder)
|
||||||
|
@ -234,15 +234,15 @@
|
|||||||
new and the variadic arguments.
|
new and the variadic arguments.
|
||||||
|
|
||||||
The majority of the work is done by the public \l QGlobalStatic class and
|
The majority of the work is done by the public \l QGlobalStatic class and
|
||||||
the private \c QtGlobalStatic::Holder class. The \c Holder class has a
|
the private \c QtGlobalStatic::Holder class. The \c Holder union has a
|
||||||
non-static, trivial member of suitable size and alignment to hold \a TYPE
|
single non-static member of type \a TYPE, but because this is a union, its
|
||||||
(a \c{std::aligned_union_t} or a \c{std::aligned_storage_t}). The
|
construction and destruction are explicitly controlled in the Holder's
|
||||||
constructor calls the "QGS" type's static member function with a pointer to
|
constructor and destructor. The constructor calls the "QGS" type's static
|
||||||
this location so it can be initialized and the destructor calls the type's
|
member function with a pointer to this member so it can be initialized
|
||||||
destructor. The \c{Holder} type is therefore neither trivially
|
and the destructor calls the type's destructor. The \c{Holder} type is
|
||||||
constructible nor trivially destructible. It is used as a function-local \c
|
therefore neither trivially constructible nor trivially destructible. It is
|
||||||
static so its initialization is thread-safe due to C++11's requirement that
|
used as a function-local \c static so its initialization is thread-safe due
|
||||||
such variables be thread-safely initialized.
|
to C++11's requirement that such variables be thread-safely initialized.
|
||||||
|
|
||||||
Additionally, both the constructor and destructor modify a guard variable
|
Additionally, both the constructor and destructor modify a guard variable
|
||||||
after construction and before destruction, respectively. The guard variable
|
after construction and before destruction, respectively. The guard variable
|
||||||
|
Loading…
x
Reference in New Issue
Block a user