Warning, file /include/QtCore/qatomicscopedvaluerollback.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 #ifndef QATOMICSCOPEDVALUEROLLBACK_H
0005 #define QATOMICSCOPEDVALUEROLLBACK_H
0006
0007 #include <QtCore/qassert.h>
0008 #include <QtCore/qatomic.h>
0009 #include <QtCore/qcompilerdetection.h>
0010 #include <QtCore/qtclasshelpermacros.h>
0011 #include <QtCore/qtconfigmacros.h>
0012
0013 #include <atomic>
0014
0015 QT_BEGIN_NAMESPACE
0016
0017 template <typename T>
0018 class QAtomicScopedValueRollback
0019 {
0020 std::atomic<T> &m_atomic;
0021 T m_value;
0022 std::memory_order m_mo;
0023
0024 Q_DISABLE_COPY_MOVE(QAtomicScopedValueRollback)
0025
0026 static constexpr std::memory_order store_part(std::memory_order mo) noexcept
0027 {
0028 switch (mo) {
0029 case std::memory_order_relaxed:
0030 case std::memory_order_consume:
0031 case std::memory_order_acquire: return std::memory_order_relaxed;
0032 case std::memory_order_release:
0033 case std::memory_order_acq_rel: return std::memory_order_release;
0034 case std::memory_order_seq_cst: return std::memory_order_seq_cst;
0035 }
0036
0037 #if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
0038
0039 Q_UNREACHABLE();
0040 #endif
0041 return std::memory_order_seq_cst;
0042 }
0043
0044 static constexpr std::memory_order load_part(std::memory_order mo) noexcept
0045 {
0046 switch (mo) {
0047 case std::memory_order_relaxed:
0048 case std::memory_order_release: return std::memory_order_relaxed;
0049 case std::memory_order_consume: return std::memory_order_consume;
0050 case std::memory_order_acquire:
0051 case std::memory_order_acq_rel: return std::memory_order_acquire;
0052 case std::memory_order_seq_cst: return std::memory_order_seq_cst;
0053 }
0054
0055 #if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
0056
0057 Q_UNREACHABLE();
0058 #endif
0059 return std::memory_order_seq_cst;
0060 }
0061 public:
0062
0063
0064
0065 Q_NODISCARD_CTOR
0066 explicit constexpr
0067 QAtomicScopedValueRollback(std::atomic<T> &var,
0068 std::memory_order mo = std::memory_order_seq_cst)
0069 : m_atomic(var), m_value(var.load(load_part(mo))), m_mo(mo) {}
0070
0071 Q_NODISCARD_CTOR
0072 explicit constexpr
0073 QAtomicScopedValueRollback(std::atomic<T> &var, T value,
0074 std::memory_order mo = std::memory_order_seq_cst)
0075 : m_atomic(var), m_value(var.exchange(value, mo)), m_mo(mo) {}
0076
0077
0078
0079
0080 Q_NODISCARD_CTOR
0081 explicit constexpr
0082 QAtomicScopedValueRollback(QBasicAtomicInteger<T> &var,
0083 std::memory_order mo = std::memory_order_seq_cst)
0084 : QAtomicScopedValueRollback(var._q_value, mo) {}
0085
0086 Q_NODISCARD_CTOR
0087 explicit constexpr
0088 QAtomicScopedValueRollback(QBasicAtomicInteger<T> &var, T value,
0089 std::memory_order mo = std::memory_order_seq_cst)
0090 : QAtomicScopedValueRollback(var._q_value, value, mo) {}
0091
0092
0093
0094
0095 Q_NODISCARD_CTOR
0096 explicit constexpr
0097 QAtomicScopedValueRollback(QBasicAtomicPointer<std::remove_pointer_t<T>> &var,
0098 std::memory_order mo = std::memory_order_seq_cst)
0099 : QAtomicScopedValueRollback(var._q_value, mo) {}
0100
0101 Q_NODISCARD_CTOR
0102 explicit constexpr
0103 QAtomicScopedValueRollback(QBasicAtomicPointer<std::remove_pointer_t<T>> &var, T value,
0104 std::memory_order mo = std::memory_order_seq_cst)
0105 : QAtomicScopedValueRollback(var._q_value, value, mo) {}
0106
0107 ~QAtomicScopedValueRollback()
0108 {
0109 m_atomic.store(m_value, store_part(m_mo));
0110 }
0111
0112 void commit()
0113 {
0114 m_value = m_atomic.load(load_part(m_mo));
0115 }
0116 };
0117
0118 template <typename T>
0119 QAtomicScopedValueRollback(QBasicAtomicPointer<T> &)
0120 -> QAtomicScopedValueRollback<T*>;
0121 template <typename T>
0122 QAtomicScopedValueRollback(QBasicAtomicPointer<T> &, std::memory_order)
0123 -> QAtomicScopedValueRollback<T*>;
0124
0125 QT_END_NAMESPACE
0126
0127 #endif