File indexing completed on 2026-09-06 09:18:15
0001
0002
0003
0004
0005
0006 #ifndef QTYPEINFO_H
0007 #define QTYPEINFO_H
0008
0009 #include <QtCore/qcompilerdetection.h>
0010 #include <QtCore/qcontainerfwd.h>
0011
0012 #include <type_traits>
0013
0014 QT_BEGIN_NAMESPACE
0015
0016 class QDebug;
0017
0018
0019
0020
0021
0022 namespace QtPrivate {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 template <typename T>
0033 inline constexpr bool qIsComplex =
0034 !std::is_trivially_default_constructible_v<T> || !std::is_trivially_copyable_v<T>;
0035
0036
0037
0038
0039
0040
0041
0042
0043 template <typename T>
0044 inline constexpr bool qIsRelocatable = std::is_trivially_copyable_v<T> && std::is_trivially_destructible_v<T>;
0045
0046
0047
0048
0049
0050
0051
0052 template <typename T>
0053 inline constexpr bool qIsValueInitializationBitwiseZero =
0054 std::is_scalar_v<T> && !std::is_member_object_pointer_v<T>;
0055
0056 }
0057
0058
0059
0060
0061
0062 template <typename T>
0063 class QTypeInfo
0064 {
0065 public:
0066 enum {
0067 isPointer [[deprecated("Use std::is_pointer instead")]] = std::is_pointer_v<T>,
0068 isIntegral [[deprecated("Use std::is_integral instead")]] = std::is_integral_v<T>,
0069 isComplex = QtPrivate::qIsComplex<T>,
0070 isRelocatable = QtPrivate::qIsRelocatable<T>,
0071 isValueInitializationBitwiseZero = QtPrivate::qIsValueInitializationBitwiseZero<T>,
0072 };
0073 };
0074
0075 template<>
0076 class QTypeInfo<void>
0077 {
0078 public:
0079 enum {
0080 isPointer [[deprecated("Use std::is_pointer instead")]] = false,
0081 isIntegral [[deprecated("Use std::is_integral instead")]] = false,
0082 isComplex = false,
0083 isRelocatable = false,
0084 isValueInitializationBitwiseZero = false,
0085 };
0086 };
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108 template <class T, class...Ts>
0109 class QTypeInfoMerger
0110 {
0111 static_assert(sizeof...(Ts) > 0);
0112 public:
0113 static constexpr bool isComplex = ((QTypeInfo<Ts>::isComplex) || ...);
0114 static constexpr bool isRelocatable = ((QTypeInfo<Ts>::isRelocatable) && ...);
0115 [[deprecated("Use std::is_pointer instead")]] static constexpr bool isPointer = false;
0116 [[deprecated("Use std::is_integral instead")]] static constexpr bool isIntegral = false;
0117 static constexpr bool isValueInitializationBitwiseZero = false;
0118 static_assert(!isRelocatable ||
0119 std::is_copy_constructible_v<T> ||
0120 std::is_move_constructible_v<T>,
0121 "All Ts... are Q_RELOCATABLE_TYPE, but T is neither copy- nor move-constructible, "
0122 "so cannot be Q_RELOCATABLE_TYPE. Please mark T as Q_COMPLEX_TYPE manually.");
0123 };
0124
0125
0126
0127
0128 template <class T1, class T2>
0129 class QTypeInfo<std::pair<T1, T2>> : public QTypeInfoMerger<std::pair<T1, T2>, T1, T2> {};
0130
0131 #define Q_DECLARE_MOVABLE_CONTAINER(CONTAINER) \
0132 template <typename ...T> \
0133 class QTypeInfo<CONTAINER<T...>> \
0134 { \
0135 public: \
0136 enum { \
0137 isPointer [[deprecated("Use std::is_pointer instead")]] = false, \
0138 isIntegral [[deprecated("Use std::is_integral instead")]] = false, \
0139 isComplex = true, \
0140 isRelocatable = true, \
0141 isValueInitializationBitwiseZero = false, \
0142 }; \
0143 }
0144
0145 Q_DECLARE_MOVABLE_CONTAINER(QList);
0146 Q_DECLARE_MOVABLE_CONTAINER(QQueue);
0147 Q_DECLARE_MOVABLE_CONTAINER(QStack);
0148 Q_DECLARE_MOVABLE_CONTAINER(QSet);
0149 Q_DECLARE_MOVABLE_CONTAINER(QMap);
0150 Q_DECLARE_MOVABLE_CONTAINER(QMultiMap);
0151 Q_DECLARE_MOVABLE_CONTAINER(QHash);
0152 Q_DECLARE_MOVABLE_CONTAINER(QMultiHash);
0153 Q_DECLARE_MOVABLE_CONTAINER(QCache);
0154
0155 #undef Q_DECLARE_MOVABLE_CONTAINER
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165 enum {
0166 Q_COMPLEX_TYPE = 0,
0167 Q_PRIMITIVE_TYPE = 0x1,
0168 Q_RELOCATABLE_TYPE = 0x2,
0169 Q_MOVABLE_TYPE = 0x2,
0170 Q_DUMMY_TYPE = 0x4,
0171 };
0172
0173 #define Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS) \
0174 class QTypeInfo<TYPE > \
0175 { \
0176 public: \
0177 enum { \
0178 isComplex = (((FLAGS) & Q_PRIMITIVE_TYPE) == 0) && QtPrivate::qIsComplex<TYPE>, \
0179 isRelocatable = !isComplex || ((FLAGS) & Q_RELOCATABLE_TYPE) || QtPrivate::qIsRelocatable<TYPE>, \
0180 isPointer [[deprecated("Use std::is_pointer instead")]] = std::is_pointer_v< TYPE >, \
0181 isIntegral [[deprecated("Use std::is_integral instead")]] = std::is_integral< TYPE >::value, \
0182 isValueInitializationBitwiseZero = QtPrivate::qIsValueInitializationBitwiseZero<TYPE>, \
0183 }; \
0184 static_assert(!QTypeInfo<TYPE>::isRelocatable || \
0185 std::is_copy_constructible_v<TYPE > || \
0186 std::is_move_constructible_v<TYPE >, \
0187 #TYPE " is neither copy- nor move-constructible, so cannot be Q_RELOCATABLE_TYPE"); \
0188 }
0189
0190 #define Q_DECLARE_TYPEINFO(TYPE, FLAGS) \
0191 template<> \
0192 Q_DECLARE_TYPEINFO_BODY(TYPE, FLAGS)
0193
0194
0195 template<typename T> class QFlags;
0196 template<typename T>
0197 Q_DECLARE_TYPEINFO_BODY(QFlags<T>, Q_PRIMITIVE_TYPE);
0198
0199 QT_END_NAMESPACE
0200 #endif