LCOV - code coverage report
Current view: top level - home/aheinecke/dev/main/qt5/include/QtCore - qatomic_cxx11.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 6 6 100.0 %
Date: 2018-11-14 16:53:58 Functions: 4 4 100.0 %

          Line data    Source code
       1             : /****************************************************************************
       2             : **
       3             : ** Copyright (C) 2011 Thiago Macieira <thiago@kde.org>
       4             : ** Copyright (C) 2016 Intel Corporation.
       5             : ** Contact: https://www.qt.io/licensing/
       6             : **
       7             : ** This file is part of the QtCore module of the Qt Toolkit.
       8             : **
       9             : ** $QT_BEGIN_LICENSE:LGPL$
      10             : ** Commercial License Usage
      11             : ** Licensees holding valid commercial Qt licenses may use this file in
      12             : ** accordance with the commercial license agreement provided with the
      13             : ** Software or, alternatively, in accordance with the terms contained in
      14             : ** a written agreement between you and The Qt Company. For licensing terms
      15             : ** and conditions see https://www.qt.io/terms-conditions. For further
      16             : ** information use the contact form at https://www.qt.io/contact-us.
      17             : **
      18             : ** GNU Lesser General Public License Usage
      19             : ** Alternatively, this file may be used under the terms of the GNU Lesser
      20             : ** General Public License version 3 as published by the Free Software
      21             : ** Foundation and appearing in the file LICENSE.LGPL3 included in the
      22             : ** packaging of this file. Please review the following information to
      23             : ** ensure the GNU Lesser General Public License version 3 requirements
      24             : ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
      25             : **
      26             : ** GNU General Public License Usage
      27             : ** Alternatively, this file may be used under the terms of the GNU
      28             : ** General Public License version 2.0 or (at your option) the GNU General
      29             : ** Public license version 3 or any later version approved by the KDE Free
      30             : ** Qt Foundation. The licenses are as published by the Free Software
      31             : ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
      32             : ** included in the packaging of this file. Please review the following
      33             : ** information to ensure the GNU General Public License requirements will
      34             : ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
      35             : ** https://www.gnu.org/licenses/gpl-3.0.html.
      36             : **
      37             : ** $QT_END_LICENSE$
      38             : **
      39             : ****************************************************************************/
      40             : 
      41             : #ifndef QATOMIC_CXX11_H
      42             : #define QATOMIC_CXX11_H
      43             : 
      44             : #include <QtCore/qgenericatomic.h>
      45             : #include <atomic>
      46             : 
      47             : QT_BEGIN_NAMESPACE
      48             : 
      49             : #if 0
      50             : // silence syncqt warnings
      51             : QT_END_NAMESPACE
      52             : #pragma qt_sync_skip_header_check
      53             : #pragma qt_sync_stop_processing
      54             : #endif
      55             : 
      56             : /* Attempt to detect whether the atomic operations exist in hardware
      57             :  * or whether they are emulated by way of a lock.
      58             :  *
      59             :  * C++11 29.4 [atomics.lockfree] p1 says
      60             :  *
      61             :  *  The ATOMIC_..._LOCK_FREE macros indicate the lock-free property of the
      62             :  *  corresponding atomic types, with the signed and unsigned variants grouped
      63             :  *  together. The properties also apply to the corresponding (partial)
      64             :  *  specializations of the atomic template. A value of 0 indicates that the
      65             :  *  types are never lock-free. A value of 1 indicates that the types are
      66             :  *  sometimes lock-free. A value of 2 indicates that the types are always
      67             :  *  lock-free.
      68             :  *
      69             :  * We have a problem when the value is 1: we'd need to check at runtime, but
      70             :  * QAtomicInteger requires a constexpr answer (defect introduced in Qt 5.0). So
      71             :  * we'll err in the side of caution and say it isn't.
      72             :  */
      73             : 
      74             : // ### Qt 6: make non-constexpr (see above)
      75             : template <int N> struct QAtomicTraits
      76             : { static Q_DECL_CONSTEXPR inline bool isLockFree(); };
      77             : 
      78             : #define Q_ATOMIC_INT32_IS_SUPPORTED
      79             : #if ATOMIC_INT_LOCK_FREE == 2
      80             : #  define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
      81             : #  define Q_ATOMIC_INT_TEST_AND_SET_IS_ALWAYS_NATIVE
      82             : #  define Q_ATOMIC_INT_FETCH_AND_STORE_IS_ALWAYS_NATIVE
      83             : #  define Q_ATOMIC_INT_FETCH_AND_ADD_IS_ALWAYS_NATIVE
      84             : #  define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
      85             : #  define Q_ATOMIC_INT32_TEST_AND_SET_IS_ALWAYS_NATIVE
      86             : #  define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_ALWAYS_NATIVE
      87             : #  define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_ALWAYS_NATIVE
      88             : 
      89             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<4>::isLockFree()
      90             : { return true; }
      91             : #elif ATOMIC_INT_LOCK_FREE == 1
      92             : #  define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
      93             : #  define Q_ATOMIC_INT_TEST_AND_SET_IS_SOMETIMES_NATIVE
      94             : #  define Q_ATOMIC_INT_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
      95             : #  define Q_ATOMIC_INT_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
      96             : #  define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
      97             : #  define Q_ATOMIC_INT32_TEST_AND_SET_IS_SOMETIMES_NATIVE
      98             : #  define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
      99             : #  define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
     100             : 
     101             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<4>::isLockFree()
     102             : { return false; }
     103             : #else
     104             : #  define Q_ATOMIC_INT_REFERENCE_COUNTING_IS_NEVER_NATIVE
     105             : #  define Q_ATOMIC_INT_TEST_AND_SET_IS_NEVER_NATIVE
     106             : #  define Q_ATOMIC_INT_FETCH_AND_STORE_IS_NEVER_NATIVE
     107             : #  define Q_ATOMIC_INT_FETCH_AND_ADD_IS_NEVER_NATIVE
     108             : #  define Q_ATOMIC_INT32_REFERENCE_COUNTING_IS_NEVER_NATIVE
     109             : #  define Q_ATOMIC_INT32_TEST_AND_SET_IS_NEVER_NATIVE
     110             : #  define Q_ATOMIC_INT32_FETCH_AND_STORE_IS_NEVER_NATIVE
     111             : #  define Q_ATOMIC_INT32_FETCH_AND_ADD_IS_NEVER_NATIVE
     112             : 
     113             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<4>::isLockFree()
     114             : { return false; }
     115             : #endif
     116             : 
     117             : #if ATOMIC_POINTER_LOCK_FREE == 2
     118             : #  define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
     119             : #  define Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE
     120             : #  define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_ALWAYS_NATIVE
     121             : #  define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_ALWAYS_NATIVE
     122             : #elif ATOMIC_POINTER_LOCK_FREE == 1
     123             : #  define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
     124             : #  define Q_ATOMIC_POINTER_TEST_AND_SET_IS_SOMETIMES_NATIVE
     125             : #  define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
     126             : #  define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
     127             : #else
     128             : #  define Q_ATOMIC_POINTER_REFERENCE_COUNTING_IS_NEVER_NATIVE
     129             : #  define Q_ATOMIC_POINTER_TEST_AND_SET_IS_NEVER_NATIVE
     130             : #  define Q_ATOMIC_POINTER_FETCH_AND_STORE_IS_NEVER_NATIVE
     131             : #  define Q_ATOMIC_POINTER_FETCH_AND_ADD_IS_NEVER_NATIVE
     132             : #endif
     133             : 
     134             : template<> struct QAtomicOpsSupport<1> { enum { IsSupported = 1 }; };
     135             : #define Q_ATOMIC_INT8_IS_SUPPORTED
     136             : #if ATOMIC_CHAR_LOCK_FREE == 2
     137             : #  define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
     138             : #  define Q_ATOMIC_INT8_TEST_AND_SET_IS_ALWAYS_NATIVE
     139             : #  define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_ALWAYS_NATIVE
     140             : #  define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_ALWAYS_NATIVE
     141             : 
     142             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<1>::isLockFree()
     143             : { return true; }
     144             : #elif ATOMIC_CHAR_LOCK_FREE == 1
     145             : #  define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
     146             : #  define Q_ATOMIC_INT8_TEST_AND_SET_IS_SOMETIMES_NATIVE
     147             : #  define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
     148             : #  define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
     149             : 
     150             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<1>::isLockFree()
     151             : { return false; }
     152             : #else
     153             : #  define Q_ATOMIC_INT8_REFERENCE_COUNTING_IS_NEVER_NATIVE
     154             : #  define Q_ATOMIC_INT8_TEST_AND_SET_IS_NEVER_NATIVE
     155             : #  define Q_ATOMIC_INT8_FETCH_AND_STORE_IS_NEVER_NATIVE
     156             : #  define Q_ATOMIC_INT8_FETCH_AND_ADD_IS_NEVER_NATIVE
     157             : 
     158             : template <> Q_DECL_CONSTEXPR bool QAtomicTraits<1>::isLockFree()
     159             : { return false; }
     160             : #endif
     161             : 
     162             : template<> struct QAtomicOpsSupport<2> { enum { IsSupported = 1 }; };
     163             : #define Q_ATOMIC_INT16_IS_SUPPORTED
     164             : #if ATOMIC_SHORT_LOCK_FREE == 2
     165             : #  define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
     166             : #  define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
     167             : #  define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
     168             : #  define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
     169             : 
     170             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<2>::isLockFree()
     171             : { return false; }
     172             : #elif ATOMIC_SHORT_LOCK_FREE == 1
     173             : #  define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
     174             : #  define Q_ATOMIC_INT16_TEST_AND_SET_IS_SOMETIMES_NATIVE
     175             : #  define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
     176             : #  define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
     177             : 
     178             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<2>::isLockFree()
     179             : { return false; }
     180             : #else
     181             : #  define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_NEVER_NATIVE
     182             : #  define Q_ATOMIC_INT16_TEST_AND_SET_IS_NEVER_NATIVE
     183             : #  define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_NEVER_NATIVE
     184             : #  define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_NEVER_NATIVE
     185             : 
     186             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<2>::isLockFree()
     187             : { return false; }
     188             : #endif
     189             : 
     190             : #if QT_CONFIG(std_atomic64)
     191             : template<> struct QAtomicOpsSupport<8> { enum { IsSupported = 1 }; };
     192             : #  define Q_ATOMIC_INT64_IS_SUPPORTED
     193             : #  if ATOMIC_LLONG_LOCK_FREE == 2
     194             : #    define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_ALWAYS_NATIVE
     195             : #    define Q_ATOMIC_INT16_TEST_AND_SET_IS_ALWAYS_NATIVE
     196             : #    define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_ALWAYS_NATIVE
     197             : #    define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_ALWAYS_NATIVE
     198             : 
     199             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<8>::isLockFree()
     200             : { return true; }
     201             : #  elif ATOMIC_LLONG_LOCK_FREE == 1
     202             : #    define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_SOMETIMES_NATIVE
     203             : #    define Q_ATOMIC_INT16_TEST_AND_SET_IS_SOMETIMES_NATIVE
     204             : #    define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_SOMETIMES_NATIVE
     205             : #    define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_SOMETIMES_NATIVE
     206             : 
     207             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<8>::isLockFree()
     208             : { return false; }
     209             : #  else
     210             : #    define Q_ATOMIC_INT16_REFERENCE_COUNTING_IS_NEVER_NATIVE
     211             : #    define Q_ATOMIC_INT16_TEST_AND_SET_IS_NEVER_NATIVE
     212             : #    define Q_ATOMIC_INT16_FETCH_AND_STORE_IS_NEVER_NATIVE
     213             : #    define Q_ATOMIC_INT16_FETCH_AND_ADD_IS_NEVER_NATIVE
     214             : 
     215             : template <> Q_DECL_CONSTEXPR inline bool QAtomicTraits<8>::isLockFree()
     216             : { return false; }
     217             : #  endif
     218             : #endif
     219             : 
     220             : template <typename X> struct QAtomicOps
     221             : {
     222             :     typedef std::atomic<X> Type;
     223             : 
     224             :     template <typename T> static inline
     225       24643 :     T load(const std::atomic<T> &_q_value) Q_DECL_NOTHROW
     226             :     {
     227       49263 :         return _q_value.load(std::memory_order_relaxed);
     228             :     }
     229             : 
     230             :     template <typename T> static inline
     231             :     T load(const volatile std::atomic<T> &_q_value) Q_DECL_NOTHROW
     232             :     {
     233             :         return _q_value.load(std::memory_order_relaxed);
     234             :     }
     235             : 
     236             :     template <typename T> static inline
     237             :     T loadAcquire(const std::atomic<T> &_q_value) Q_DECL_NOTHROW
     238             :     {
     239             :         return _q_value.load(std::memory_order_acquire);
     240             :     }
     241             : 
     242             :     template <typename T> static inline
     243             :     T loadAcquire(const volatile std::atomic<T> &_q_value) Q_DECL_NOTHROW
     244             :     {
     245             :         return _q_value.load(std::memory_order_acquire);
     246             :     }
     247             : 
     248             :     template <typename T> static inline
     249             :     void store(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
     250             :     {
     251             :         _q_value.store(newValue, std::memory_order_relaxed);
     252             :     }
     253             : 
     254             :     template <typename T> static inline
     255             :     void storeRelease(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
     256             :     {
     257             :         _q_value.store(newValue, std::memory_order_release);
     258             :     }
     259             : 
     260             :     static inline Q_DECL_CONSTEXPR bool isReferenceCountingNative() Q_DECL_NOTHROW { return isTestAndSetNative(); }
     261             :     static inline Q_DECL_CONSTEXPR bool isReferenceCountingWaitFree() Q_DECL_NOTHROW { return false; }
     262             :     template <typename T>
     263        5747 :     static inline bool ref(std::atomic<T> &_q_value)
     264             :     {
     265        5747 :         return ++_q_value != 0;
     266             :     }
     267             : 
     268             :     template <typename T>
     269       10336 :     static inline bool deref(std::atomic<T> &_q_value) Q_DECL_NOTHROW
     270             :     {
     271       10336 :         return --_q_value != 0;
     272             :     }
     273             : 
     274             :     static inline Q_DECL_CONSTEXPR bool isTestAndSetNative() Q_DECL_NOTHROW
     275             :     { return QAtomicTraits<sizeof(X)>::isLockFree(); }
     276             :     static inline Q_DECL_CONSTEXPR bool isTestAndSetWaitFree() Q_DECL_NOTHROW { return false; }
     277             : 
     278             :     template <typename T>
     279             :     static bool testAndSetRelaxed(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
     280             :     {
     281             :         bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_relaxed, std::memory_order_relaxed);
     282             :         if (currentValue)
     283             :             *currentValue = expectedValue;
     284             :         return tmp;
     285             :     }
     286             : 
     287             :     template <typename T>
     288             :     static bool testAndSetAcquire(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
     289             :     {
     290             :         bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acquire, std::memory_order_acquire);
     291             :         if (currentValue)
     292             :             *currentValue = expectedValue;
     293             :         return tmp;
     294             :     }
     295             : 
     296             :     template <typename T>
     297             :     static bool testAndSetRelease(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
     298             :     {
     299             :         bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_release, std::memory_order_relaxed);
     300             :         if (currentValue)
     301             :             *currentValue = expectedValue;
     302             :         return tmp;
     303             :     }
     304             : 
     305             :     template <typename T>
     306             :     static bool testAndSetOrdered(std::atomic<T> &_q_value, T expectedValue, T newValue, T *currentValue = Q_NULLPTR) Q_DECL_NOTHROW
     307             :     {
     308             :         bool tmp = _q_value.compare_exchange_strong(expectedValue, newValue, std::memory_order_acq_rel, std::memory_order_acquire);
     309             :         if (currentValue)
     310             :             *currentValue = expectedValue;
     311             :         return tmp;
     312             :     }
     313             : 
     314             :     static inline Q_DECL_CONSTEXPR bool isFetchAndStoreNative() Q_DECL_NOTHROW { return isTestAndSetNative(); }
     315             :     static inline Q_DECL_CONSTEXPR bool isFetchAndStoreWaitFree() Q_DECL_NOTHROW { return false; }
     316             : 
     317             :     template <typename T>
     318             :     static T fetchAndStoreRelaxed(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
     319             :     {
     320             :         return _q_value.exchange(newValue, std::memory_order_relaxed);
     321             :     }
     322             : 
     323             :     template <typename T>
     324             :     static T fetchAndStoreAcquire(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
     325             :     {
     326             :         return _q_value.exchange(newValue, std::memory_order_acquire);
     327             :     }
     328             : 
     329             :     template <typename T>
     330             :     static T fetchAndStoreRelease(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
     331             :     {
     332             :         return _q_value.exchange(newValue, std::memory_order_release);
     333             :     }
     334             : 
     335             :     template <typename T>
     336             :     static T fetchAndStoreOrdered(std::atomic<T> &_q_value, T newValue) Q_DECL_NOTHROW
     337             :     {
     338             :         return _q_value.exchange(newValue, std::memory_order_acq_rel);
     339             :     }
     340             : 
     341             :     static inline Q_DECL_CONSTEXPR bool isFetchAndAddNative() Q_DECL_NOTHROW { return isTestAndSetNative(); }
     342             :     static inline Q_DECL_CONSTEXPR bool isFetchAndAddWaitFree() Q_DECL_NOTHROW { return false; }
     343             : 
     344             :     template <typename T> static inline
     345             :     T fetchAndAddRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     346             :     {
     347             :         return _q_value.fetch_add(valueToAdd, std::memory_order_relaxed);
     348             :     }
     349             : 
     350             :     template <typename T> static inline
     351             :     T fetchAndAddAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     352             :     {
     353             :         return _q_value.fetch_add(valueToAdd, std::memory_order_acquire);
     354             :     }
     355             : 
     356             :     template <typename T> static inline
     357             :     T fetchAndAddRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     358             :     {
     359             :         return _q_value.fetch_add(valueToAdd, std::memory_order_release);
     360             :     }
     361             : 
     362             :     template <typename T> static inline
     363             :     T fetchAndAddOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     364             :     {
     365             :         return _q_value.fetch_add(valueToAdd, std::memory_order_acq_rel);
     366             :     }
     367             : 
     368             :     template <typename T> static inline
     369             :     T fetchAndSubRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     370             :     {
     371             :         return _q_value.fetch_sub(valueToAdd, std::memory_order_relaxed);
     372             :     }
     373             : 
     374             :     template <typename T> static inline
     375             :     T fetchAndSubAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     376             :     {
     377             :         return _q_value.fetch_sub(valueToAdd, std::memory_order_acquire);
     378             :     }
     379             : 
     380             :     template <typename T> static inline
     381             :     T fetchAndSubRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     382             :     {
     383             :         return _q_value.fetch_sub(valueToAdd, std::memory_order_release);
     384             :     }
     385             : 
     386             :     template <typename T> static inline
     387             :     T fetchAndSubOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     388             :     {
     389             :         return _q_value.fetch_sub(valueToAdd, std::memory_order_acq_rel);
     390             :     }
     391             : 
     392             :     template <typename T> static inline
     393             :     T fetchAndAndRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     394             :     {
     395             :         return _q_value.fetch_and(valueToAdd, std::memory_order_relaxed);
     396             :     }
     397             : 
     398             :     template <typename T> static inline
     399             :     T fetchAndAndAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     400             :     {
     401             :         return _q_value.fetch_and(valueToAdd, std::memory_order_acquire);
     402             :     }
     403             : 
     404             :     template <typename T> static inline
     405             :     T fetchAndAndRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     406             :     {
     407             :         return _q_value.fetch_and(valueToAdd, std::memory_order_release);
     408             :     }
     409             : 
     410             :     template <typename T> static inline
     411             :     T fetchAndAndOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     412             :     {
     413             :         return _q_value.fetch_and(valueToAdd, std::memory_order_acq_rel);
     414             :     }
     415             : 
     416             :     template <typename T> static inline
     417             :     T fetchAndOrRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     418             :     {
     419             :         return _q_value.fetch_or(valueToAdd, std::memory_order_relaxed);
     420             :     }
     421             : 
     422             :     template <typename T> static inline
     423             :     T fetchAndOrAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     424             :     {
     425             :         return _q_value.fetch_or(valueToAdd, std::memory_order_acquire);
     426             :     }
     427             : 
     428             :     template <typename T> static inline
     429             :     T fetchAndOrRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     430             :     {
     431             :         return _q_value.fetch_or(valueToAdd, std::memory_order_release);
     432             :     }
     433             : 
     434             :     template <typename T> static inline
     435             :     T fetchAndOrOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     436             :     {
     437             :         return _q_value.fetch_or(valueToAdd, std::memory_order_acq_rel);
     438             :     }
     439             : 
     440             :     template <typename T> static inline
     441             :     T fetchAndXorRelaxed(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     442             :     {
     443             :         return _q_value.fetch_xor(valueToAdd, std::memory_order_relaxed);
     444             :     }
     445             : 
     446             :     template <typename T> static inline
     447             :     T fetchAndXorAcquire(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     448             :     {
     449             :         return _q_value.fetch_xor(valueToAdd, std::memory_order_acquire);
     450             :     }
     451             : 
     452             :     template <typename T> static inline
     453             :     T fetchAndXorRelease(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     454             :     {
     455             :         return _q_value.fetch_xor(valueToAdd, std::memory_order_release);
     456             :     }
     457             : 
     458             :     template <typename T> static inline
     459             :     T fetchAndXorOrdered(std::atomic<T> &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
     460             :     {
     461             :         return _q_value.fetch_xor(valueToAdd, std::memory_order_acq_rel);
     462             :     }
     463             : };
     464             : 
     465             : #if defined(Q_COMPILER_CONSTEXPR) && defined(Q_COMPILER_DEFAULT_MEMBERS) && defined(Q_COMPILER_DELETE_MEMBERS)
     466             : #  define Q_BASIC_ATOMIC_INITIALIZER(a)     { a }
     467             : #else
     468             : #  define Q_BASIC_ATOMIC_INITIALIZER(a)     { ATOMIC_VAR_INIT(a) }
     469             : #endif
     470             : 
     471             : QT_END_NAMESPACE
     472             : 
     473             : #endif // QATOMIC_CXX0X_H

Generated by: LCOV version 1.13