File indexing completed on 2026-07-18 08:43:02
0001
0002
0003
0004
0005 #ifndef QSCOPEDPOINTER_H
0006 #define QSCOPEDPOINTER_H
0007
0008 #include <QtCore/qglobal.h>
0009
0010 #include <stdlib.h>
0011
0012 QT_BEGIN_NAMESPACE
0013
0014 template <typename T>
0015 struct QScopedPointerDeleter
0016 {
0017 static inline void cleanup(T *pointer) noexcept
0018 {
0019
0020
0021
0022 typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
0023 (void) sizeof(IsIncompleteType);
0024
0025 delete pointer;
0026 }
0027 void operator()(T *pointer) const noexcept
0028 {
0029 cleanup(pointer);
0030 }
0031 };
0032
0033 template <typename T>
0034 struct QScopedPointerArrayDeleter
0035 {
0036 static inline void cleanup(T *pointer) noexcept
0037 {
0038
0039
0040
0041 typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ];
0042 (void) sizeof(IsIncompleteType);
0043
0044 delete[] pointer;
0045 }
0046 void operator()(T *pointer) const noexcept
0047 {
0048 cleanup(pointer);
0049 }
0050 };
0051
0052 struct QScopedPointerPodDeleter
0053 {
0054 static inline void cleanup(void *pointer) noexcept { free(pointer); }
0055 void operator()(void *pointer) const noexcept { cleanup(pointer); }
0056 };
0057
0058 #ifndef QT_NO_QOBJECT
0059 template <typename T>
0060 struct QScopedPointerObjectDeleteLater
0061 {
0062 static inline void cleanup(T *pointer) { if (pointer) pointer->deleteLater(); }
0063 void operator()(T *pointer) const { cleanup(pointer); }
0064 };
0065
0066 class QObject;
0067 typedef QScopedPointerObjectDeleteLater<QObject> QScopedPointerDeleteLater;
0068 #endif
0069
0070 template <typename T, typename Cleanup = QScopedPointerDeleter<T> >
0071 class QScopedPointer
0072 {
0073 public:
0074 Q_NODISCARD_CTOR
0075 explicit QScopedPointer(T *p = nullptr) noexcept : d(p)
0076 {
0077 }
0078
0079 inline ~QScopedPointer()
0080 {
0081 T *oldD = this->d;
0082 Cleanup::cleanup(oldD);
0083 }
0084
0085 inline T &operator*() const
0086 {
0087 Q_ASSERT(d);
0088 return *d;
0089 }
0090
0091 T *operator->() const noexcept
0092 {
0093 return d;
0094 }
0095
0096 bool operator!() const noexcept
0097 {
0098 return !d;
0099 }
0100
0101 explicit operator bool() const
0102 {
0103 return !isNull();
0104 }
0105
0106 T *data() const noexcept
0107 {
0108 return d;
0109 }
0110
0111 T *get() const noexcept
0112 {
0113 return d;
0114 }
0115
0116 bool isNull() const noexcept
0117 {
0118 return !d;
0119 }
0120
0121 void reset(T *other = nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval<T *>())))
0122 {
0123 if (d == other)
0124 return;
0125 T *oldD = std::exchange(d, other);
0126 Cleanup::cleanup(oldD);
0127 }
0128
0129 #if QT_DEPRECATED_SINCE(6, 1)
0130 QT_DEPRECATED_VERSION_X_6_1("Use std::unique_ptr instead, and call release().")
0131 T *take() noexcept
0132 {
0133 T *oldD = std::exchange(d, nullptr);
0134 return oldD;
0135 }
0136 #endif
0137
0138 #if QT_DEPRECATED_SINCE(6, 2)
0139 QT_DEPRECATED_VERSION_X_6_2("Use std::unique_ptr instead of QScopedPointer.")
0140 void swap(QScopedPointer<T, Cleanup> &other) noexcept
0141 {
0142 qt_ptr_swap(d, other.d);
0143 }
0144 #endif
0145
0146 typedef T *pointer;
0147
0148 friend bool operator==(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) noexcept
0149 {
0150 return lhs.data() == rhs.data();
0151 }
0152
0153 friend bool operator!=(const QScopedPointer<T, Cleanup> &lhs, const QScopedPointer<T, Cleanup> &rhs) noexcept
0154 {
0155 return lhs.data() != rhs.data();
0156 }
0157
0158 friend bool operator==(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) noexcept
0159 {
0160 return lhs.isNull();
0161 }
0162
0163 friend bool operator==(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) noexcept
0164 {
0165 return rhs.isNull();
0166 }
0167
0168 friend bool operator!=(const QScopedPointer<T, Cleanup> &lhs, std::nullptr_t) noexcept
0169 {
0170 return !lhs.isNull();
0171 }
0172
0173 friend bool operator!=(std::nullptr_t, const QScopedPointer<T, Cleanup> &rhs) noexcept
0174 {
0175 return !rhs.isNull();
0176 }
0177
0178 #if QT_DEPRECATED_SINCE(6, 2)
0179 QT_DEPRECATED_VERSION_X_6_2("Use std::unique_ptr instead of QScopedPointer.")
0180 friend void swap(QScopedPointer<T, Cleanup> &p1, QScopedPointer<T, Cleanup> &p2) noexcept
0181 { p1.swap(p2); }
0182 #endif
0183
0184 protected:
0185 T *d;
0186
0187 private:
0188 Q_DISABLE_COPY_MOVE(QScopedPointer)
0189 };
0190
0191 template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> >
0192 class QScopedArrayPointer : public QScopedPointer<T, Cleanup>
0193 {
0194 template <typename Ptr>
0195 using if_same_type = typename std::enable_if<std::is_same<typename std::remove_cv<T>::type, Ptr>::value, bool>::type;
0196 public:
0197 Q_NODISCARD_CTOR
0198 inline QScopedArrayPointer() : QScopedPointer<T, Cleanup>(nullptr) {}
0199 inline ~QScopedArrayPointer() = default;
0200
0201 template <typename D, if_same_type<D> = true>
0202 Q_NODISCARD_CTOR
0203 explicit QScopedArrayPointer(D *p)
0204 : QScopedPointer<T, Cleanup>(p)
0205 {
0206 }
0207
0208 T &operator[](qsizetype i)
0209 {
0210 return this->d[i];
0211 }
0212
0213 const T &operator[](qsizetype i) const
0214 {
0215 return this->d[i];
0216 }
0217
0218 #if QT_DEPRECATED_SINCE(6, 2)
0219 QT_DEPRECATED_VERSION_X_6_2("Use std::unique_ptr instead of QScopedArrayPointer.")
0220 void swap(QScopedArrayPointer &other) noexcept
0221 { QScopedPointer<T, Cleanup>::swap(other); }
0222 #endif
0223
0224 private:
0225 explicit inline QScopedArrayPointer(void *)
0226 {
0227
0228
0229
0230
0231
0232
0233
0234
0235 }
0236
0237 Q_DISABLE_COPY_MOVE(QScopedArrayPointer)
0238 };
0239
0240 #if QT_DEPRECATED_SINCE(6, 2)
0241 template <typename T, typename Cleanup>
0242 QT_DEPRECATED_VERSION_X_6_2("Use std::unique_ptr instead of QScopedArrayPointer.")
0243 inline void swap(QScopedArrayPointer<T, Cleanup> &lhs, QScopedArrayPointer<T, Cleanup> &rhs) noexcept
0244 { lhs.swap(rhs); }
0245 #endif
0246
0247 QT_END_NAMESPACE
0248
0249 #endif