4#ifndef QATOMICSCOPEDVALUEROLLBACK_H
5#define QATOMICSCOPEDVALUEROLLBACK_H
7#include <QtCore/qassert.h>
8#include <QtCore/qatomic.h>
9#include <QtCore/qcompilerdetection.h>
10#include <QtCore/qtclasshelpermacros.h>
11#include <QtCore/qtconfigmacros.h>
19class QAtomicScopedValueRollback
21 std::atomic<T> &m_atomic;
23 std::memory_order m_mo;
25 Q_DISABLE_COPY_MOVE(QAtomicScopedValueRollback)
27 static constexpr std::memory_order store_part(std::memory_order mo)
noexcept
30 case std::memory_order_relaxed:
31 case std::memory_order_consume:
32 case std::memory_order_acquire:
return std::memory_order_relaxed;
33 case std::memory_order_release:
34 case std::memory_order_acq_rel:
return std::memory_order_release;
35 case std::memory_order_seq_cst:
return std::memory_order_seq_cst;
38#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900
)
42 return std::memory_order_seq_cst;
45 static constexpr std::memory_order load_part(std::memory_order mo)
noexcept
48 case std::memory_order_relaxed:
49 case std::memory_order_release:
return std::memory_order_relaxed;
50 case std::memory_order_consume:
return std::memory_order_consume;
51 case std::memory_order_acquire:
52 case std::memory_order_acq_rel:
return std::memory_order_acquire;
53 case std::memory_order_seq_cst:
return std::memory_order_seq_cst;
56#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900
)
60 return std::memory_order_seq_cst;
68 QAtomicScopedValueRollback(std::atomic<T> &var,
69 std::memory_order mo = std::memory_order_seq_cst)
70 : m_atomic(var), m_value(var.load(load_part(mo))), m_mo(mo) {}
74 QAtomicScopedValueRollback(std::atomic<T> &var, T value,
75 std::memory_order mo = std::memory_order_seq_cst)
76 : m_atomic(var), m_value(var.exchange(value, mo)), m_mo(mo) {}
83 QAtomicScopedValueRollback(QBasicAtomicInteger<T> &var,
84 std::memory_order mo = std::memory_order_seq_cst)
85 : QAtomicScopedValueRollback(var._q_value, mo) {}
89 QAtomicScopedValueRollback(QBasicAtomicInteger<T> &var, T value,
90 std::memory_order mo = std::memory_order_seq_cst)
91 : QAtomicScopedValueRollback(var._q_value, value, mo) {}
98 QAtomicScopedValueRollback(QBasicAtomicPointer<std::remove_pointer_t<T>> &var,
99 std::memory_order mo = std::memory_order_seq_cst)
100 : QAtomicScopedValueRollback(var._q_value, mo) {}
104 QAtomicScopedValueRollback(QBasicAtomicPointer<std::remove_pointer_t<T>> &var, T value,
105 std::memory_order mo = std::memory_order_seq_cst)
106 : QAtomicScopedValueRollback(var._q_value, value, mo) {}
108 ~QAtomicScopedValueRollback()
110 m_atomic.store(m_value, store_part(m_mo));
115 m_value = m_atomic.load(load_part(m_mo));
123QAtomicScopedValueRollback(QBasicAtomicPointer<T> &, std::memory_order)
124 -> QAtomicScopedValueRollback<T*>;
126template <
typename T,
typename V,
127 std::enable_if_t<std::is_convertible_v<V, T>,
bool> =
true>
128QAtomicScopedValueRollback(std::atomic<T>&, V)
129 -> QAtomicScopedValueRollback<T>;
130template <
typename T,
typename V,
131 std::enable_if_t<std::is_convertible_v<V, T>,
bool> =
true>
132QAtomicScopedValueRollback(std::atomic<T>&, V, std::memory_order)
133 -> QAtomicScopedValueRollback<T>;
135template <
typename T,
typename V,
136 std::enable_if_t<std::is_convertible_v<V, T>,
bool> =
true>
137QAtomicScopedValueRollback(QBasicAtomicInteger<T>&, V)
138 -> QAtomicScopedValueRollback<T>;
139template <
typename T,
typename V,
140 std::enable_if_t<std::is_convertible_v<V, T>,
bool> =
true>
141QAtomicScopedValueRollback(QBasicAtomicInteger<T>&, V, std::memory_order)
142 -> QAtomicScopedValueRollback<T>;
144template <
typename T,
typename V,
145 std::enable_if_t<std::is_convertible_v<V, T*>,
bool> =
true>
146QAtomicScopedValueRollback(QBasicAtomicPointer<T>&, V)
147 -> QAtomicScopedValueRollback<T*>;
148template <
typename T,
typename V,
149 std::enable_if_t<std::is_convertible_v<V, T*>,
bool> =
true>
150QAtomicScopedValueRollback(QBasicAtomicPointer<T>&, V, std::memory_order)
151 -> QAtomicScopedValueRollback<T*>;
QAtomicScopedValueRollback(QBasicAtomicPointer< T > &) -> QAtomicScopedValueRollback< T * >