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
};
template <typename QGS> struct Holder
template <typename QGS> union Holder
{
using Type = typename QGS::QGS_Type;
using PlainType = std::remove_cv_t<Type>;
static constexpr bool ConstructionIsNoexcept = noexcept(QGS::innerFunction(nullptr));
std::aligned_union_t<1, PlainType> storage;
static inline QBasicAtomicInteger<qint8> guard = { QtGlobalStatic::Uninitialized };
// union's sole member
PlainType storage;
Holder() noexcept(ConstructionIsNoexcept)
{
QGS::innerFunction(pointer());
@ -81,7 +83,7 @@ template <typename QGS> struct Holder
PlainType *pointer() noexcept
{
return reinterpret_cast<PlainType *>(&storage);
return &storage;
}
Q_DISABLE_COPY_MOVE(Holder)

View File

@ -234,15 +234,15 @@
new and the variadic arguments.
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
non-static, trivial member of suitable size and alignment to hold \a TYPE
(a \c{std::aligned_union_t} or a \c{std::aligned_storage_t}). The
constructor calls the "QGS" type's static member function with a pointer to
this location so it can be initialized and the destructor calls the type's
destructor. The \c{Holder} type is therefore neither trivially
constructible nor trivially destructible. It is used as a function-local \c
static so its initialization is thread-safe due to C++11's requirement that
such variables be thread-safely initialized.
the private \c QtGlobalStatic::Holder class. The \c Holder union has a
single non-static member of type \a TYPE, but because this is a union, its
construction and destruction are explicitly controlled in the Holder's
constructor and destructor. The constructor calls the "QGS" type's static
member function with a pointer to this member so it can be initialized
and the destructor calls the type's destructor. The \c{Holder} type is
therefore neither trivially constructible nor trivially destructible. It is
used as a function-local \c static so its initialization is thread-safe due
to C++11's requirement that such variables be thread-safely initialized.
Additionally, both the constructor and destructor modify a guard variable
after construction and before destruction, respectively. The guard variable