1 /**************************************************************************** 2 ** 3 ** DQt - D bindings for the Qt Toolkit 4 ** 5 ** GNU Lesser General Public License Usage 6 ** This file may be used under the terms of the GNU Lesser 7 ** General Public License version 3 as published by the Free Software 8 ** Foundation and appearing in the file LICENSE.LGPL3 included in the 9 ** packaging of this file. Please review the following information to 10 ** ensure the GNU Lesser General Public License version 3 requirements 11 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. 12 ** 13 ****************************************************************************/ 14 module qt.core.basicatomic; 15 extern(C++): 16 17 import core.atomic; 18 import qt.config; 19 import qt.helpers; 20 version(D_LP64) 21 import core.stdc.config; 22 23 /+ #ifndef QBASICATOMIC_H +/ 24 /+ #define QBASICATOMIC_H 25 26 #if defined(QT_BOOTSTRAPPED) 27 // If C++11 atomics are supported, use them! 28 // Note that constexpr support is sometimes disabled in QNX or INTEGRITY builds, 29 // but their libraries have <atomic>. 30 #elif defined(Q_COMPILER_ATOMICS) && (defined(Q_COMPILER_CONSTEXPR) || defined(Q_OS_QNX) || defined(Q_OS_INTEGRITY)) 31 // We only support one fallback: MSVC, because even on version 2015, it lacks full constexpr support 32 #elif defined(Q_CC_MSVC) 33 // No fallback 34 #else 35 # error "Qt requires C++11 support" 36 #endif 37 38 QT_WARNING_PUSH 39 QT_WARNING_DISABLE_MSVC(4522) 40 41 42 #if 0 43 // silence syncqt warnings 44 #pragma qt_no_master_include 45 #pragma qt_sync_stop_processing 46 #endif 47 48 // New atomics 49 50 #if defined(Q_COMPILER_CONSTEXPR) 51 # if defined(Q_CC_CLANG) && Q_CC_CLANG < 303 52 /* 53 Do not define QT_BASIC_ATOMIC_HAS_CONSTRUCTORS for Clang before version 3.3. 54 For details about the bug: see http://llvm.org/bugs/show_bug.cgi?id=12670 55 */ 56 # else 57 # define QT_BASIC_ATOMIC_HAS_CONSTRUCTORS 58 # endif 59 #endif +/ 60 61 extern(C++, class) struct QBasicAtomicInteger(T) 62 { 63 public: 64 alias Type = T; 65 //alias Ops = QAtomicOps!(T); 66 // static check that this is a valid integer 67 /+ Q_STATIC_ASSERT_X(QTypeInfo<T>::isIntegral, "template parameter is not an integral type") +/ 68 // /+ Q_STATIC_ASSERT_X(QAtomicOpsSupport<sizeof(T)>::IsSupported, "template parameter is an integral of a size not supported on this platform") +/static assert(cast(bool)(QAtomicOpsSupport!(T.sizeof).IsSupported),"template parameter is an integral of a size not supported on this platform"); 69 70 Type _q_value; 71 72 // Everything below is either implemented in ../arch/qatomic_XXX.h or (as fallback) in qgenericatomic.h 73 /+ #if QT_DEPRECATED_SINCE(5, 14) +/ 74 // /+ QT_DEPRECATED_VERSION_X_5_14("Use loadRelaxed") +/ T load() const/+ noexcept+/ { return loadRelaxed(); } 75 // /+ QT_DEPRECATED_VERSION_X_5_14("Use storeRelaxed") +/ void store(T newValue)/+ noexcept+/ { storeRelaxed(newValue); } 76 /+ #endif +/ 77 78 T loadRelaxed() const/+ noexcept+/ 79 { 80 return atomicLoad!(MemoryOrder.raw)(_q_value); 81 } 82 // void storeRelaxed(T newValue)/+ noexcept+/ { Ops.storeRelaxed(_q_value, newValue); } 83 84 T loadAcquire() const/+ noexcept+/{ return atomicLoad!(MemoryOrder.acq)(_q_value); } 85 void storeRelease(T newValue)/+ noexcept+/ { atomicStore!(MemoryOrder.rel)(_q_value, newValue); } 86 /+auto opCast(T : T)() const/+ noexcept+/ { return loadAcquire(); }+/ 87 /+T operator =(T newValue)/+ noexcept+/ { storeRelease(newValue); return newValue; }+/ 88 89 // static bool isReferenceCountingNative()/+ noexcept+/ { return Ops.isReferenceCountingNative(); } 90 // static bool isReferenceCountingWaitFree()/+ noexcept+/ { return Ops.isReferenceCountingWaitFree(); } 91 92 bool ref_()/+ noexcept+/ 93 { 94 return atomicFetchAdd(_q_value, 1) + 1 != 0; 95 } 96 bool deref()/+ noexcept+/ 97 { 98 return atomicFetchSub(_q_value, 1) - 1 != 0; 99 } 100 101 // static bool isTestAndSetNative()/+ noexcept+/ { return Ops.isTestAndSetNative(); } 102 // static bool isTestAndSetWaitFree()/+ noexcept+/ { return Ops.isTestAndSetWaitFree(); } 103 104 bool testAndSetRelaxed(T expectedValue, T newValue)/+ noexcept+/ 105 { 106 bool tmp = cas!(MemoryOrder.raw, MemoryOrder.raw)(&_q_value, expectedValue, newValue); 107 return tmp; 108 } 109 /+ bool testAndSetAcquire(T expectedValue, T newValue)/+ noexcept+/ 110 { return Ops.testAndSetAcquire(_q_value, expectedValue, newValue); } 111 bool testAndSetRelease(T expectedValue, T newValue)/+ noexcept+/ 112 { return Ops.testAndSetRelease(_q_value, expectedValue, newValue); } 113 bool testAndSetOrdered(T expectedValue, T newValue)/+ noexcept+/ 114 { return Ops.testAndSetOrdered(_q_value, expectedValue, newValue); } 115 +/ 116 /+bool testAndSetRelaxed(T expectedValue, T newValue, ref T currentValue)/+ noexcept+/ 117 { return Ops.testAndSetRelaxed(_q_value, expectedValue, newValue, ¤tValue); }+ 118 bool testAndSetAcquire(T expectedValue, T newValue, ref T currentValue)/+ noexcept+/ 119 { return Ops.testAndSetAcquire(_q_value, expectedValue, newValue, ¤tValue); } 120 bool testAndSetRelease(T expectedValue, T newValue, ref T currentValue)/+ noexcept+/ 121 { return Ops.testAndSetRelease(_q_value, expectedValue, newValue, ¤tValue); } 122 bool testAndSetOrdered(T expectedValue, T newValue, ref T currentValue)/+ noexcept+/ 123 { return Ops.testAndSetOrdered(_q_value, expectedValue, newValue, ¤tValue); } 124 +/ 125 // static bool isFetchAndStoreNative()/+ noexcept+/ { return Ops.isFetchAndStoreNative(); } 126 // static bool isFetchAndStoreWaitFree()/+ noexcept+/ { return Ops.isFetchAndStoreWaitFree(); } 127 128 /* T fetchAndStoreRelaxed(T newValue)/+ noexcept+/ 129 { return Ops.fetchAndStoreRelaxed(_q_value, newValue); } 130 T fetchAndStoreAcquire(T newValue)/+ noexcept+/ 131 { return Ops.fetchAndStoreAcquire(_q_value, newValue); } 132 T fetchAndStoreRelease(T newValue)/+ noexcept+/ 133 { return Ops.fetchAndStoreRelease(_q_value, newValue); } 134 T fetchAndStoreOrdered(T newValue)/+ noexcept+/ 135 { return Ops.fetchAndStoreOrdered(_q_value, newValue); }*/ 136 137 // static bool isFetchAndAddNative()/+ noexcept+/ { return Ops.isFetchAndAddNative(); } 138 // static bool isFetchAndAddWaitFree()/+ noexcept+/ { return Ops.isFetchAndAddWaitFree(); } 139 140 /+ T fetchAndAddRelaxed(T valueToAdd)/+ noexcept+/ 141 { return Ops.fetchAndAddRelaxed(_q_value, valueToAdd); } 142 T fetchAndAddAcquire(T valueToAdd)/+ noexcept+/ 143 { return Ops.fetchAndAddAcquire(_q_value, valueToAdd); } 144 T fetchAndAddRelease(T valueToAdd)/+ noexcept+/ 145 { return Ops.fetchAndAddRelease(_q_value, valueToAdd); } 146 T fetchAndAddOrdered(T valueToAdd)/+ noexcept+/ 147 { return Ops.fetchAndAddOrdered(_q_value, valueToAdd); } 148 149 T fetchAndSubRelaxed(T valueToAdd)/+ noexcept+/ 150 { return Ops.fetchAndSubRelaxed(_q_value, valueToAdd); } 151 T fetchAndSubAcquire(T valueToAdd)/+ noexcept+/ 152 { return Ops.fetchAndSubAcquire(_q_value, valueToAdd); } 153 T fetchAndSubRelease(T valueToAdd)/+ noexcept+/ 154 { return Ops.fetchAndSubRelease(_q_value, valueToAdd); } 155 T fetchAndSubOrdered(T valueToAdd)/+ noexcept+/ 156 { return Ops.fetchAndSubOrdered(_q_value, valueToAdd); } 157 158 T fetchAndAndRelaxed(T valueToAdd)/+ noexcept+/ 159 { return Ops.fetchAndAndRelaxed(_q_value, valueToAdd); } 160 T fetchAndAndAcquire(T valueToAdd)/+ noexcept+/ 161 { return Ops.fetchAndAndAcquire(_q_value, valueToAdd); } 162 T fetchAndAndRelease(T valueToAdd)/+ noexcept+/ 163 { return Ops.fetchAndAndRelease(_q_value, valueToAdd); } 164 T fetchAndAndOrdered(T valueToAdd)/+ noexcept+/ 165 { return Ops.fetchAndAndOrdered(_q_value, valueToAdd); } 166 167 T fetchAndOrRelaxed(T valueToAdd)/+ noexcept+/ 168 { return Ops.fetchAndOrRelaxed(_q_value, valueToAdd); } 169 T fetchAndOrAcquire(T valueToAdd)/+ noexcept+/ 170 { return Ops.fetchAndOrAcquire(_q_value, valueToAdd); } 171 T fetchAndOrRelease(T valueToAdd)/+ noexcept+/ 172 { return Ops.fetchAndOrRelease(_q_value, valueToAdd); } 173 T fetchAndOrOrdered(T valueToAdd)/+ noexcept+/ 174 { return Ops.fetchAndOrOrdered(_q_value, valueToAdd); } 175 176 T fetchAndXorRelaxed(T valueToAdd)/+ noexcept+/ 177 { return Ops.fetchAndXorRelaxed(_q_value, valueToAdd); } 178 T fetchAndXorAcquire(T valueToAdd)/+ noexcept+/ 179 { return Ops.fetchAndXorAcquire(_q_value, valueToAdd); } 180 T fetchAndXorRelease(T valueToAdd)/+ noexcept+/ 181 { return Ops.fetchAndXorRelease(_q_value, valueToAdd); } 182 T fetchAndXorOrdered(T valueToAdd)/+ noexcept+/ 183 { return Ops.fetchAndXorOrdered(_q_value, valueToAdd); } 184 +/ 185 T opUnary(string op)()/+ noexcept+/ if(op == "++") 186 { return fetchAndAddOrdered(1) + 1; } 187 /+T operator ++(int)/+ noexcept+/ 188 { return fetchAndAddOrdered(1); }+/ 189 T opUnary(string op)()/+ noexcept+/ if(op == "--") 190 { return fetchAndSubOrdered(1) - 1; } 191 /+T operator --(int)/+ noexcept+/ 192 { return fetchAndSubOrdered(1); }+/ 193 194 T opOpAssign(string op)(T v)/+ noexcept+/ if(op == "+") 195 { return fetchAndAddOrdered(v) + v; } 196 T opOpAssign(string op)(T v)/+ noexcept+/ if(op == "-") 197 { return fetchAndSubOrdered(v) - v; } 198 T opOpAssign(string op)(T v)/+ noexcept+/ if(op == "&") 199 { return fetchAndAndOrdered(v) & v; } 200 T opOpAssign(string op)(T v)/+ noexcept+/ if(op == "|") 201 { return fetchAndOrOrdered(v) | v; } 202 /+T operator ^=(T v)/+ noexcept+/ 203 { return fetchAndXorOrdered(v) ^ v; }+/ 204 205 206 /+ #ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS 207 QBasicAtomicInteger() = default; 208 constexpr QBasicAtomicInteger(T value) noexcept : _q_value(value) {} 209 QBasicAtomicInteger(const QBasicAtomicInteger &) = delete; 210 QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) = delete; 211 QBasicAtomicInteger &operator=(const QBasicAtomicInteger &) volatile = delete; 212 #endif +/ 213 } 214 alias QBasicAtomicInt = QBasicAtomicInteger!(int); 215 216 /+ template <typename X> 217 class QBasicAtomicPointer 218 { 219 public: 220 typedef X *Type; 221 typedef QAtomicOps<Type> Ops; 222 typedef typename Ops::Type AtomicType; 223 224 AtomicType _q_value; 225 226 #if QT_DEPRECATED_SINCE(5, 14) 227 QT_DEPRECATED_VERSION_X_5_14("Use loadRelaxed") Type load() const noexcept { return loadRelaxed(); } 228 QT_DEPRECATED_VERSION_X_5_14("Use storeRelaxed") void store(Type newValue) noexcept { storeRelaxed(newValue); } 229 #endif 230 231 Type loadRelaxed() const noexcept { return Ops::loadRelaxed(_q_value); } 232 void storeRelaxed(Type newValue) noexcept { Ops::storeRelaxed(_q_value, newValue); } 233 234 operator Type() const noexcept { return loadAcquire(); } 235 Type operator=(Type newValue) noexcept { storeRelease(newValue); return newValue; } 236 237 // Atomic API, implemented in qatomic_XXX.h 238 Type loadAcquire() const noexcept { return Ops::loadAcquire(_q_value); } 239 void storeRelease(Type newValue) noexcept { Ops::storeRelease(_q_value, newValue); } 240 241 static bool isTestAndSetNative() noexcept { return Ops::isTestAndSetNative(); } 242 static bool isTestAndSetWaitFree() noexcept { return Ops::isTestAndSetWaitFree(); } 243 244 bool testAndSetRelaxed(Type expectedValue, Type newValue) noexcept 245 { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue); } 246 bool testAndSetAcquire(Type expectedValue, Type newValue) noexcept 247 { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue); } 248 bool testAndSetRelease(Type expectedValue, Type newValue) noexcept 249 { return Ops::testAndSetRelease(_q_value, expectedValue, newValue); } 250 bool testAndSetOrdered(Type expectedValue, Type newValue) noexcept 251 { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue); } 252 253 bool testAndSetRelaxed(Type expectedValue, Type newValue, Type ¤tValue) noexcept 254 { return Ops::testAndSetRelaxed(_q_value, expectedValue, newValue, ¤tValue); } 255 bool testAndSetAcquire(Type expectedValue, Type newValue, Type ¤tValue) noexcept 256 { return Ops::testAndSetAcquire(_q_value, expectedValue, newValue, ¤tValue); } 257 bool testAndSetRelease(Type expectedValue, Type newValue, Type ¤tValue) noexcept 258 { return Ops::testAndSetRelease(_q_value, expectedValue, newValue, ¤tValue); } 259 bool testAndSetOrdered(Type expectedValue, Type newValue, Type ¤tValue) noexcept 260 { return Ops::testAndSetOrdered(_q_value, expectedValue, newValue, ¤tValue); } 261 262 static bool isFetchAndStoreNative() noexcept { return Ops::isFetchAndStoreNative(); } 263 static bool isFetchAndStoreWaitFree() noexcept { return Ops::isFetchAndStoreWaitFree(); } 264 265 Type fetchAndStoreRelaxed(Type newValue) noexcept 266 { return Ops::fetchAndStoreRelaxed(_q_value, newValue); } 267 Type fetchAndStoreAcquire(Type newValue) noexcept 268 { return Ops::fetchAndStoreAcquire(_q_value, newValue); } 269 Type fetchAndStoreRelease(Type newValue) noexcept 270 { return Ops::fetchAndStoreRelease(_q_value, newValue); } 271 Type fetchAndStoreOrdered(Type newValue) noexcept 272 { return Ops::fetchAndStoreOrdered(_q_value, newValue); } 273 274 static bool isFetchAndAddNative() noexcept { return Ops::isFetchAndAddNative(); } 275 static bool isFetchAndAddWaitFree() noexcept { return Ops::isFetchAndAddWaitFree(); } 276 277 Type fetchAndAddRelaxed(qptrdiff valueToAdd) noexcept 278 { return Ops::fetchAndAddRelaxed(_q_value, valueToAdd); } 279 Type fetchAndAddAcquire(qptrdiff valueToAdd) noexcept 280 { return Ops::fetchAndAddAcquire(_q_value, valueToAdd); } 281 Type fetchAndAddRelease(qptrdiff valueToAdd) noexcept 282 { return Ops::fetchAndAddRelease(_q_value, valueToAdd); } 283 Type fetchAndAddOrdered(qptrdiff valueToAdd) noexcept 284 { return Ops::fetchAndAddOrdered(_q_value, valueToAdd); } 285 286 Type fetchAndSubRelaxed(qptrdiff valueToAdd) noexcept 287 { return Ops::fetchAndSubRelaxed(_q_value, valueToAdd); } 288 Type fetchAndSubAcquire(qptrdiff valueToAdd) noexcept 289 { return Ops::fetchAndSubAcquire(_q_value, valueToAdd); } 290 Type fetchAndSubRelease(qptrdiff valueToAdd) noexcept 291 { return Ops::fetchAndSubRelease(_q_value, valueToAdd); } 292 Type fetchAndSubOrdered(qptrdiff valueToAdd) noexcept 293 { return Ops::fetchAndSubOrdered(_q_value, valueToAdd); } 294 295 Type operator++() noexcept 296 { return fetchAndAddOrdered(1) + 1; } 297 Type operator++(int) noexcept 298 { return fetchAndAddOrdered(1); } 299 Type operator--() noexcept 300 { return fetchAndSubOrdered(1) - 1; } 301 Type operator--(int) noexcept 302 { return fetchAndSubOrdered(1); } 303 Type operator+=(qptrdiff valueToAdd) noexcept 304 { return fetchAndAddOrdered(valueToAdd) + valueToAdd; } 305 Type operator-=(qptrdiff valueToSub) noexcept 306 { return fetchAndSubOrdered(valueToSub) - valueToSub; } 307 308 #ifdef QT_BASIC_ATOMIC_HAS_CONSTRUCTORS 309 QBasicAtomicPointer() = default; 310 constexpr QBasicAtomicPointer(Type value) noexcept : _q_value(value) {} 311 QBasicAtomicPointer(const QBasicAtomicPointer &) = delete; 312 QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) = delete; 313 QBasicAtomicPointer &operator=(const QBasicAtomicPointer &) volatile = delete; 314 #endif 315 }; 316 317 #ifndef Q_BASIC_ATOMIC_INITIALIZER 318 # define Q_BASIC_ATOMIC_INITIALIZER(a) { (a) } 319 #endif 320 321 322 QT_WARNING_POP +/ 323 324 /+ #endif +/ // QBASICATOMIC_H 325