Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-11 08:50:22

0001 // Copyright (C) 2011 Thiago Macieira <thiago@kde.org>
0002 // Copyright (C) 2016 Intel Corporation.
0003 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
0004 // Qt-Security score:significant reason:default
0005 
0006 #ifndef QATOMIC_CXX11_H
0007 #define QATOMIC_CXX11_H
0008 
0009 #include <QtCore/qgenericatomic.h>
0010 #include <QtCore/qyieldcpu.h>
0011 #include <atomic>
0012 
0013 QT_BEGIN_NAMESPACE
0014 
0015 #if 0
0016 // silence syncqt warnings
0017 QT_END_NAMESPACE
0018 #pragma qt_sync_skip_header_check
0019 #pragma qt_sync_stop_processing
0020 #endif
0021 
0022 /* Attempt to detect whether the atomic operations exist in hardware
0023  * or whether they are emulated by way of a lock.
0024  *
0025  * C++11 29.4 [atomics.lockfree] p1 says
0026  *
0027  *  The ATOMIC_..._LOCK_FREE macros indicate the lock-free property of the
0028  *  corresponding atomic types, with the signed and unsigned variants grouped
0029  *  together. The properties also apply to the corresponding (partial)
0030  *  specializations of the atomic template. A value of 0 indicates that the
0031  *  types are never lock-free. A value of 1 indicates that the types are
0032  *  sometimes lock-free. A value of 2 indicates that the types are always
0033  *  lock-free.
0034  *
0035  * We have a problem when the value is 1: we'd need to check at runtime, but
0036  * QAtomicInteger requires a constexpr answer (defect introduced in Qt 5.0). So
0037  * we'll err in the side of caution and say it isn't.
0038  */
0039 template <int N> struct QAtomicTraits
0040 { static inline bool isLockFree(); };
0041 
0042 #define Q_ATOMIC_INT32_IS_SUPPORTED
0043 #if ATOMIC_INT_LOCK_FREE == 2
0044 #  define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
0045 #  define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
0046 #  define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
0047 #  define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
0048 #  define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
0049 #  define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE
0050 #  define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE
0051 #  define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE
0052 
0053 template <> inline bool QAtomicTraits<4>::isLockFree()
0054 { return true; }
0055 #elif ATOMIC_INT_LOCK_FREE == 1
0056 #  define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
0057 #  define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
0058 #  define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
0059 #  define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
0060 #  define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
0061 #  define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE
0062 #  define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
0063 #  define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
0064 
0065 template <> inline bool QAtomicTraits<4>::isLockFree()
0066 { return false; }
0067 #else
0068 #  define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NEVER_NATIVE
0069 #  define Q_ATOMIC_INT_TEST_AND_SET_IS_NEVER_NATIVE
0070 #  define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NEVER_NATIVE
0071 #  define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NEVER_NATIVE
0072 #  define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NEVER_NATIVE
0073 #  define Q_ATOMIC_INT32_TEST_AND_SET_IS_NEVER_NATIVE
0074 #  define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_NEVER_NATIVE
0075 #  define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_NEVER_NATIVE
0076 
0077 template <> inline bool QAtomicTraits<4>::isLockFree()
0078 { return false; }
0079 #endif
0080 
0081 #if ATOMIC_POINTER_LOCK_FREE == 2
0082 #  define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
0083 #  define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
0084 #  define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
0085 #  define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
0086 #elif ATOMIC_POINTER_LOCK_FREE == 1
0087 #  define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
0088 #  define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
0089 #  define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
0090 #  define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
0091 #else
0092 #  define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_NEVER_NATIVE
0093 #  define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NEVER_NATIVE
0094 #  define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NEVER_NATIVE
0095 #  define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NEVER_NATIVE
0096 #endif
0097 
0098 template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; };
0099 #define Q_ATOMIC_INT8_IS_SUPPORTED
0100 #if ATOMIC_CHAR_LOCK_FREE == 2
0101 #  define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
0102 #  define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE
0103 #  define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE
0104 #  define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE
0105 
0106 template <> inline bool QAtomicTraits<1>::isLockFree()
0107 { return true; }
0108 #elif ATOMIC_CHAR_LOCK_FREE == 1
0109 #  define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
0110 #  define Q_ATOMIC_INT8_TEST_AND_SET_IS_SOMETIMES_NATIVE
0111 #  define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
0112 #  define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
0113 
0114 template <> inline bool QAtomicTraits<1>::isLockFree()
0115 { return false; }
0116 #else
0117 #  define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_NEVER_NATIVE
0118 #  define Q_ATOMIC_INT8_TEST_AND_SET_IS_NEVER_NATIVE
0119 #  define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_NEVER_NATIVE
0120 #  define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_NEVER_NATIVE
0121 
0122 template <> bool QAtomicTraits<1>::isLockFree()
0123 { return false; }
0124 #endif
0125 
0126 template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
0127 #define Q_ATOMIC_INT16_IS_SUPPORTED
0128 #if ATOMIC_SHORT_LOCK_FREE == 2
0129 #  define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
0130 #  define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
0131 #  define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
0132 #  define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
0133 
0134 template <> inline bool QAtomicTraits<2>::isLockFree()
0135 { return false; }
0136 #elif ATOMIC_SHORT_LOCK_FREE == 1
0137 #  define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
0138 #  define Q_ATOMIC_INT16_TEST_AND_SET_IS_SOMETIMES_NATIVE
0139 #  define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
0140 #  define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
0141 
0142 template <> inline bool QAtomicTraits<2>::isLockFree()
0143 { return false; }
0144 #else
0145 #  define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_NEVER_NATIVE
0146 #  define Q_ATOMIC_INT16_TEST_AND_SET_IS_NEVER_NATIVE
0147 #  define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_NEVER_NATIVE
0148 #  define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_NEVER_NATIVE
0149 
0150 template <> inline bool QAtomicTraits<2>::isLockFree()
0151 { return false; }
0152 #endif
0153 
0154 #if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(std_atomic64)
0155 template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
0156 #  define Q_ATOMIC_INT64_IS_SUPPORTED
0157 #  if ATOMIC_LLONG_LOCK_FREE == 2
0158 #    define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
0159 #    define Q_ATOMIC_INT64_TEST_AND_SET_IS_ALWAYS_NATIVE
0160 #    define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_ALWAYS_NATIVE
0161 #    define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_ALWAYS_NATIVE
0162 
0163 template <> inline bool QAtomicTraits<8>::isLockFree()
0164 { return true; }
0165 #  elif ATOMIC_LLONG_LOCK_FREE == 1
0166 #    define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
0167 #    define Q_ATOMIC_INT64_TEST_AND_SET_IS_SOMETIMES_NATIVE
0168 #    define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
0169 #    define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
0170 
0171 template <> inline bool QAtomicTraits<8>::isLockFree()
0172 { return false; }
0173 #  else
0174 #    define Q_ATOMIC_INT64_REFERENCE_COUNTING_IS_NEVER_NATIVE
0175 #    define Q_ATOMIC_INT64_TEST_AND_SET_IS_NEVER_NATIVE
0176 #    define Q_ATOMIC_INT64_FETCH_AND_STORE_IS_NEVER_NATIVE
0177 #    define Q_ATOMIC_INT64_FETCH_AND_ADD_IS_NEVER_NATIVE
0178 
0179 template <> inline bool QAtomicTraits<8>::isLockFree()
0180 { return false; }
0181 #  endif
0182 #endif
0183 
0184 template <typename X> struct QAtomicOps
0185 {
0186     typedef std::atomic<X> Type;
0187 
0188     template <typename T> static inline
0189     T load(const std::atomic<T> &_q_value) noexcept
0190     {
0191         return _q_value.load(std::memory_order_relaxed);
0192     }
0193 
0194     template <typename T> static inline
0195     T load(const volatile std::atomic<T> &_q_value) noexcept
0196     {
0197         return _q_value.load(std::memory_order_relaxed);
0198     }
0199 
0200     template <typename T> static inline
0201     T loadRelaxed(const std::atomic<T> &_q_value) noexcept
0202     {
0203         return _q_value.load(std::memory_order_relaxed);
0204     }
0205 
0206     template <typename T> static inline
0207     T loadRelaxed(const volatile std::atomic<T> &_q_value) noexcept
0208     {
0209         return _q_value.load(std::memory_order_relaxed);
0210     }
0211 
0212     template <typename T> static inline
0213     T loadAcquire(const std::atomic<T> &_q_value) noexcept
0214     {
0215         return _q_value.load(std::memory_order_acquire);
0216     }
0217 
0218     template <typename T> static inline
0219     T loadAcquire(const volatile std::atomic<T> &_q_value) noexcept
0220     {
0221         return _q_value.load(std::memory_order_acquire);
0222     }
0223 
0224     template <typename T> static inline
0225     void store(std::atomic<T> &_q_value, T newValue) noexcept
0226     {
0227         _q_value.store(newValue, std::memory_order_relaxed);
0228     }
0229 
0230     template <typename T> static inline
0231     void storeRelaxed(std::atomic<T> &_q_value, T newValue) noexcept
0232     {
0233         _q_value.store(newValue, std::memory_order_relaxed);
0234     }
0235 
0236     template <typename T> static inline
0237     void storeRelease(std::atomic<T> &_q_value, T newValue) noexcept
0238     {
0239         _q_value.store(newValue, std::memory_order_release);
0240     }
0241 
0242     static inline bool isReferenceCountingNative() noexcept { return isTestAndSetNative(); }
0243     static inline constexpr bool isReferenceCountingWaitFree() noexcept { return false; }
0244     template <typename T>
0245     static inline bool ref(std::atomic<T> &_q_value)
0246     {
0247         /* Conceptually, we want to
0248          *    return ++_q_value != 0;
0249          * However, that would be sequentially consistent, and thus stronger
0250          * than what we need. Based on
0251          * http://eel.is/c++draft/atomics.types.memop#6, we know that
0252          * pre-increment is equivalent to fetch_add(1) + 1. Unlike
0253          * pre-increment, fetch_add takes a memory order argument, so we can get
0254          * the desired acquire-release semantics.
0255          * One last gotcha is that fetch_add(1) + 1 would need to be converted
0256          * back to T, because it's susceptible to integer promotion. To sidestep
0257          * this issue and to avoid UB on signed overflow, we rewrite the
0258          * expression to:
0259          */
0260         return _q_value.fetch_add(1, std::memory_order_acq_rel) != T(-1);
0261     }
0262 
0263     template <typename T>
0264     static inline bool deref(std::atomic<T> &_q_value) noexcept
0265     {
0266         // compare with ref
0267         return _q_value.fetch_sub(1, std::memory_order_acq_rel) != T(1);
0268     }
0269 
0270     static inline bool isTestAndSetNative() noexcept
0271     { return QAtomicTraits<sizeof(X)>::isLockFree(); }
0272     static inline constexpr bool isTestAndSetWaitFree() noexcept { return false; }
0273 
0274     template <typename T>
0275     static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) noexcept
0276     {
0277         bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed, std::memory_order_relaxed);
0278         if (currentValue)
0279             *currentValue = expectedValue;
0280         return tmp;
0281     }
0282 
0283     template <typename T>
0284     static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) noexcept
0285     {
0286         bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire, std::memory_order_acquire);
0287         if (currentValue)
0288             *currentValue = expectedValue;
0289         return tmp;
0290     }
0291 
0292     template <typename T>
0293     static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) noexcept
0294     {
0295         bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release, std::memory_order_relaxed);
0296         if (currentValue)
0297             *currentValue = expectedValue;
0298         return tmp;
0299     }
0300 
0301     template <typename T>
0302     static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = nullptr) noexcept
0303     {
0304         bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel, std::memory_order_acquire);
0305         if (currentValue)
0306             *currentValue = expectedValue;
0307         return tmp;
0308     }
0309 
0310     static inline bool isFetchAndStoreNative() noexcept { return isTestAndSetNative(); }
0311     static inline constexpr bool isFetchAndStoreWaitFree() noexcept { return false; }
0312 
0313     template <typename T>
0314     static T fetchAndStoreRelaxed(std::atomic<T> &_q_value, T newValue) noexcept
0315     {
0316         return _q_value.exchange(newValue, std::memory_order_relaxed);
0317     }
0318 
0319     template <typename T>
0320     static T fetchAndStoreAcquire(std::atomic<T> &_q_value, T newValue) noexcept
0321     {
0322         return _q_value.exchange(newValue, std::memory_order_acquire);
0323     }
0324 
0325     template <typename T>
0326     static T fetchAndStoreRelease(std::atomic<T> &_q_value, T newValue) noexcept
0327     {
0328         return _q_value.exchange(newValue, std::memory_order_release);
0329     }
0330 
0331     template <typename T>
0332     static T fetchAndStoreOrdered(std::atomic<T> &_q_value, T newValue) noexcept
0333     {
0334         return _q_value.exchange(newValue, std::memory_order_acq_rel);
0335     }
0336 
0337     static inline bool isFetchAndAddNative() noexcept { return isTestAndSetNative(); }
0338     static inline constexpr bool isFetchAndAddWaitFree() noexcept { return false; }
0339 
0340     template <typename T> static inline
0341     T fetchAndAddRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0342     {
0343         return _q_value.fetch_add(valueToAdd, std::memory_order_relaxed);
0344     }
0345 
0346     template <typename T> static inline
0347     T fetchAndAddAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0348     {
0349         return _q_value.fetch_add(valueToAdd, std::memory_order_acquire);
0350     }
0351 
0352     template <typename T> static inline
0353     T fetchAndAddRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0354     {
0355         return _q_value.fetch_add(valueToAdd, std::memory_order_release);
0356     }
0357 
0358     template <typename T> static inline
0359     T fetchAndAddOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0360     {
0361         return _q_value.fetch_add(valueToAdd, std::memory_order_acq_rel);
0362     }
0363 
0364     template <typename T> static inline
0365     T fetchAndSubRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0366     {
0367         return _q_value.fetch_sub(valueToAdd, std::memory_order_relaxed);
0368     }
0369 
0370     template <typename T> static inline
0371     T fetchAndSubAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0372     {
0373         return _q_value.fetch_sub(valueToAdd, std::memory_order_acquire);
0374     }
0375 
0376     template <typename T> static inline
0377     T fetchAndSubRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0378     {
0379         return _q_value.fetch_sub(valueToAdd, std::memory_order_release);
0380     }
0381 
0382     template <typename T> static inline
0383     T fetchAndSubOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0384     {
0385         return _q_value.fetch_sub(valueToAdd, std::memory_order_acq_rel);
0386     }
0387 
0388     template <typename T> static inline
0389     T fetchAndAndRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0390     {
0391         return _q_value.fetch_and(valueToAdd, std::memory_order_relaxed);
0392     }
0393 
0394     template <typename T> static inline
0395     T fetchAndAndAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0396     {
0397         return _q_value.fetch_and(valueToAdd, std::memory_order_acquire);
0398     }
0399 
0400     template <typename T> static inline
0401     T fetchAndAndRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0402     {
0403         return _q_value.fetch_and(valueToAdd, std::memory_order_release);
0404     }
0405 
0406     template <typename T> static inline
0407     T fetchAndAndOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0408     {
0409         return _q_value.fetch_and(valueToAdd, std::memory_order_acq_rel);
0410     }
0411 
0412     template <typename T> static inline
0413     T fetchAndOrRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0414     {
0415         return _q_value.fetch_or(valueToAdd, std::memory_order_relaxed);
0416     }
0417 
0418     template <typename T> static inline
0419     T fetchAndOrAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0420     {
0421         return _q_value.fetch_or(valueToAdd, std::memory_order_acquire);
0422     }
0423 
0424     template <typename T> static inline
0425     T fetchAndOrRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0426     {
0427         return _q_value.fetch_or(valueToAdd, std::memory_order_release);
0428     }
0429 
0430     template <typename T> static inline
0431     T fetchAndOrOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0432     {
0433         return _q_value.fetch_or(valueToAdd, std::memory_order_acq_rel);
0434     }
0435 
0436     template <typename T> static inline
0437     T fetchAndXorRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0438     {
0439         return _q_value.fetch_xor(valueToAdd, std::memory_order_relaxed);
0440     }
0441 
0442     template <typename T> static inline
0443     T fetchAndXorAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0444     {
0445         return _q_value.fetch_xor(valueToAdd, std::memory_order_acquire);
0446     }
0447 
0448     template <typename T> static inline
0449     T fetchAndXorRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0450     {
0451         return _q_value.fetch_xor(valueToAdd, std::memory_order_release);
0452     }
0453 
0454     template <typename T> static inline
0455     T fetchAndXorOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) noexcept
0456     {
0457         return _q_value.fetch_xor(valueToAdd, std::memory_order_acq_rel);
0458     }
0459 };
0460 
0461 #  define Q_BASIC_ATOMIC_INITIALIZER(a)     { a }
0462 
0463 QT_END_NAMESPACE
0464 
0465 #endif // QATOMIC_CXX0X_H