File indexing completed on 2025-09-18 09:26:50
0001
0002
0003
0004 #ifndef QTHREADSTORAGE_H
0005 #define QTHREADSTORAGE_H
0006
0007 #include <QtCore/qglobal.h>
0008
0009 #if !QT_CONFIG(thread)
0010 #include <memory>
0011 #endif
0012
0013 QT_BEGIN_NAMESPACE
0014
0015 #if QT_CONFIG(thread)
0016
0017 class Q_CORE_EXPORT QThreadStorageData
0018 {
0019 public:
0020 explicit QThreadStorageData(void (*func)(void *));
0021 ~QThreadStorageData();
0022
0023 void** get() const;
0024 void** set(void* p);
0025
0026 static void finish(void**);
0027 int id;
0028 };
0029
0030
0031 template <typename T>
0032 inline
0033 T *&qThreadStorage_localData(QThreadStorageData &d, T **)
0034 {
0035 void **v = d.get();
0036 if (!v) v = d.set(nullptr);
0037 return *(reinterpret_cast<T**>(v));
0038 }
0039
0040 template <typename T>
0041 inline
0042 T *qThreadStorage_localData_const(const QThreadStorageData &d, T **)
0043 {
0044 void **v = d.get();
0045 return v ? *(reinterpret_cast<T**>(v)) : 0;
0046 }
0047
0048 template <typename T>
0049 inline
0050 void qThreadStorage_setLocalData(QThreadStorageData &d, T **t)
0051 { (void) d.set(*t); }
0052
0053 template <typename T>
0054 inline
0055 void qThreadStorage_deleteData(void *d, T **)
0056 { delete static_cast<T *>(d); }
0057
0058
0059 template <typename T>
0060 inline
0061 T &qThreadStorage_localData(QThreadStorageData &d, T *)
0062 {
0063 void **v = d.get();
0064 if (!v) v = d.set(new T());
0065 return *(reinterpret_cast<T*>(*v));
0066 }
0067
0068 template <typename T>
0069 inline
0070 T qThreadStorage_localData_const(const QThreadStorageData &d, T *)
0071 {
0072 void **v = d.get();
0073 return v ? *(reinterpret_cast<T*>(*v)) : T();
0074 }
0075
0076 template <typename T>
0077 inline
0078 void qThreadStorage_setLocalData(QThreadStorageData &d, T *t)
0079 { (void) d.set(new T(*t)); }
0080
0081 template <typename T>
0082 inline
0083 void qThreadStorage_deleteData(void *d, T *)
0084 { delete static_cast<T *>(d); }
0085
0086 template <class T>
0087 class QThreadStorage
0088 {
0089 private:
0090 QThreadStorageData d;
0091
0092 Q_DISABLE_COPY(QThreadStorage)
0093
0094 static inline void deleteData(void *x)
0095 { qThreadStorage_deleteData(x, reinterpret_cast<T*>(0)); }
0096
0097 public:
0098 inline QThreadStorage() : d(deleteData) { }
0099 inline ~QThreadStorage() { }
0100
0101 inline bool hasLocalData() const
0102 { return d.get() != nullptr; }
0103
0104 inline T& localData()
0105 { return qThreadStorage_localData(d, reinterpret_cast<T*>(0)); }
0106 inline T localData() const
0107 { return qThreadStorage_localData_const(d, reinterpret_cast<T*>(0)); }
0108
0109 inline void setLocalData(T t)
0110 { qThreadStorage_setLocalData(d, &t); }
0111 };
0112
0113 #else
0114
0115 template <typename T, typename U>
0116 inline bool qThreadStorage_hasLocalData(const std::unique_ptr<T, U> &data)
0117 {
0118 return !!data;
0119 }
0120
0121 template <typename T, typename U>
0122 inline bool qThreadStorage_hasLocalData(const std::unique_ptr<T*, U> &data)
0123 {
0124 return !!data ? *data != nullptr : false;
0125 }
0126
0127 template <typename T>
0128 inline void qThreadStorage_deleteLocalData(T *t)
0129 {
0130 delete t;
0131 }
0132
0133 template <typename T>
0134 inline void qThreadStorage_deleteLocalData(T **t)
0135 {
0136 delete *t;
0137 delete t;
0138 }
0139
0140 template <class T>
0141 class QThreadStorage
0142 {
0143 private:
0144 struct ScopedPointerThreadStorageDeleter
0145 {
0146 void operator()(T *t) const noexcept
0147 {
0148 if (t == nullptr)
0149 return;
0150 qThreadStorage_deleteLocalData(t);
0151 }
0152 };
0153 std::unique_ptr<T, ScopedPointerThreadStorageDeleter> data;
0154
0155 public:
0156 QThreadStorage() = default;
0157 ~QThreadStorage() = default;
0158 QThreadStorage(const QThreadStorage &rhs) = delete;
0159 QThreadStorage &operator=(const QThreadStorage &rhs) = delete;
0160
0161 inline bool hasLocalData() const
0162 {
0163 return qThreadStorage_hasLocalData(data);
0164 }
0165
0166 inline T &localData()
0167 {
0168 if (!data)
0169 data.reset(new T());
0170 return *data;
0171 }
0172
0173 inline T localData() const
0174 {
0175 return !!data ? *data : T();
0176 }
0177
0178 inline void setLocalData(T t)
0179 {
0180 data.reset(new T(t));
0181 }
0182 };
0183
0184 #endif
0185
0186 QT_END_NAMESPACE
0187
0188 #endif