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