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