Replace uses of std::is_trivial with its underlying definitions

C++26 deprecated it[1]. Like the paper, we don't need the trivial
default constructibility for most uses. Even some of the
QTypeInfo::isComplex checks don't need it.

[1] https://wg21.link/p3247

Pick-to: 6.8 6.5
Fixes: QTBUG-136083
Change-Id: I0caafc5a15df732b9640fffd72fb1c598563a91b
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit 97f3d41fa15a1dcaa17993436b9385ebd0fd274b)
This commit is contained in:
Thiago Macieira 2025-04-21 13:55:59 -07:00
parent 6ef945c728
commit f5faba54d1
4 changed files with 20 additions and 7 deletions

View File

@ -20,6 +20,18 @@ class QDebug;
namespace QtPrivate {
// Helper for QTypeInfo<T>::isComplex, which used to be simply
// !std::is_trivial_v but P3247 deprecated it for C++26. It used to be defined
// (since C++11) by [class]/7 as: "A trivial class is a class that is trivially
// copyable and has one or more default constructors, all of which are either
// trivial or deleted and at least one of which is not deleted. [ Note: In
// particular, a trivially copyable or trivial class does not have virtual
// functions or virtual base classes. — end note ]".
template <typename T>
inline constexpr bool qIsComplex =
!std::is_trivially_default_constructible_v<T> || !std::is_trivially_copyable_v<T>;
// A trivially copyable class must also have a trivial, non-deleted
// destructor [class.prop/1.3], CWG1734. Some implementations don't
// check for a trivial destructor, because of backwards compatibility
@ -53,7 +65,7 @@ public:
enum {
isPointer [[deprecated("Use std::is_pointer instead")]] = std::is_pointer_v<T>,
isIntegral [[deprecated("Use std::is_integral instead")]] = std::is_integral_v<T>,
isComplex = !std::is_trivial_v<T>,
isComplex = QtPrivate::qIsComplex<T>,
isRelocatable = QtPrivate::qIsRelocatable<T>,
isValueInitializationBitwiseZero = QtPrivate::qIsValueInitializationBitwiseZero<T>,
};
@ -162,7 +174,7 @@ class QTypeInfo<TYPE > \
{ \
public: \
enum { \
isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && !std::is_trivial_v<TYPE>, \
isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && QtPrivate::qIsComplex<TYPE>, \
isRelocatable = !isComplex || ((FLAGS) & Q_RELOCATABLE_TYPE) || QtPrivate::qIsRelocatable<TYPE>, \
isPointer [[deprecated("Use std::is_pointer instead")]] = std::is_pointer_v< TYPE >, \
isIntegral [[deprecated("Use std::is_integral instead")]] = std::is_integral< TYPE >::value, \

View File

@ -180,7 +180,7 @@ struct ChildError
int code;
char function[_POSIX_PIPE_BUF - sizeof(code)];
};
static_assert(std::is_trivial_v<ChildError>);
static_assert(std::is_trivially_copy_constructible_v<ChildError>);
#ifdef PIPE_BUF
static_assert(PIPE_BUF >= sizeof(ChildError)); // PIPE_BUF may be bigger
#endif

View File

@ -64,7 +64,7 @@ struct QObjectPrivate::ConnectionOrSignalVector
Connection *next;
};
};
static_assert(std::is_trivial_v<QObjectPrivate::ConnectionOrSignalVector>);
static_assert(std::is_trivially_copyable_v<QObjectPrivate::ConnectionOrSignalVector>);
struct QObjectPrivate::Connection : public ConnectionOrSignalVector
{
@ -130,8 +130,8 @@ struct QObjectPrivate::SignalVector : public ConnectionOrSignalVector
}
int count() const { return static_cast<int>(allocated); }
};
static_assert(
std::is_trivial_v<QObjectPrivate::SignalVector>); // it doesn't need to be, but it helps
// it doesn't need to be, but it helps
static_assert(std::is_trivially_copyable_v<QObjectPrivate::SignalVector>);
struct QObjectPrivate::ConnectionData
{

View File

@ -89,7 +89,8 @@ struct ByteData
QStringView asStringView() const{ return QStringView(utf16(), len / 2); }
QString asQStringRaw() const { return QString::fromRawData(utf16(), len / 2); }
};
static_assert(std::is_trivial<ByteData>::value);
static_assert(std::is_trivially_default_constructible<ByteData>::value);
static_assert(std::is_trivially_copyable<ByteData>::value);
static_assert(std::is_standard_layout<ByteData>::value);
} // namespace QtCbor