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:
Thiago Macieira 2021-12-14 16:40:19 -03:00 committed by Marc Mutz
parent e832a805c1
commit c54fb03446
2 changed files with 14 additions and 12 deletions

View File

@ -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)

View File

@ -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