Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qatomicscopedvaluerollback.h
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QATOMICSCOPEDVALUEROLLBACK_H
5#define QATOMICSCOPEDVALUEROLLBACK_H
6
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>
12
13#include <atomic>
14
16
17template <typename T>
19{
20 std::atomic<T> &m_atomic;
21 T m_value;
22 std::memory_order m_mo;
23
24 Q_DISABLE_COPY_MOVE(QAtomicScopedValueRollback)
25
26 static constexpr std::memory_order store_part(std::memory_order mo) noexcept
27 {
28 switch (mo) {
29 case std::memory_order_relaxed:
30 case std::memory_order_consume:
31 case std::memory_order_acquire: return std::memory_order_relaxed;
32 case std::memory_order_release:
33 case std::memory_order_acq_rel: return std::memory_order_release;
34 case std::memory_order_seq_cst: return std::memory_order_seq_cst;
35 }
36 // GCC 8.x does not treat __builtin_unreachable() as constexpr
37#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
38 // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
39 Q_UNREACHABLE();
40#endif
41 return std::memory_order_seq_cst;
42 }
43
44 static constexpr std::memory_order load_part(std::memory_order mo) noexcept
45 {
46 switch (mo) {
47 case std::memory_order_relaxed:
48 case std::memory_order_release: return std::memory_order_relaxed;
49 case std::memory_order_consume: return std::memory_order_consume;
50 case std::memory_order_acquire:
51 case std::memory_order_acq_rel: return std::memory_order_acquire;
52 case std::memory_order_seq_cst: return std::memory_order_seq_cst;
53 }
54 // GCC 8.x does not treat __builtin_unreachable() as constexpr
55#if !defined(Q_CC_GNU_ONLY) || (Q_CC_GNU >= 900)
56 // NOLINTNEXTLINE(qt-use-unreachable-return): Triggers on Clang, breaking GCC 8
57 Q_UNREACHABLE();
58#endif
59 return std::memory_order_seq_cst;
60 }
61public:
62 //
63 // std::atomic:
64 //
66 explicit constexpr
68 std::memory_order mo = std::memory_order_seq_cst)
69 : m_atomic(var), m_value(var.load(load_part(mo))), m_mo(mo) {}
70
72 explicit constexpr
74 std::memory_order mo = std::memory_order_seq_cst)
75 : m_atomic(var), m_value(var.exchange(value, mo)), m_mo(mo) {}
76
77 //
78 // Q(Basic)AtomicInteger:
79 //
81 explicit constexpr
82 QAtomicScopedValueRollback(QBasicAtomicInteger<T> &var,
83 std::memory_order mo = std::memory_order_seq_cst)
84 : QAtomicScopedValueRollback(var._q_value, mo) {}
85
87 explicit constexpr
88 QAtomicScopedValueRollback(QBasicAtomicInteger<T> &var, T value,
89 std::memory_order mo = std::memory_order_seq_cst)
90 : QAtomicScopedValueRollback(var._q_value, value, mo) {}
91
92 //
93 // Q(Basic)AtomicPointer:
94 //
96 explicit constexpr
98 std::memory_order mo = std::memory_order_seq_cst)
99 : QAtomicScopedValueRollback(var._q_value, mo) {}
100
102 explicit constexpr
104 std::memory_order mo = std::memory_order_seq_cst)
105 : QAtomicScopedValueRollback(var._q_value, value, mo) {}
106
108 {
109 m_atomic.store(m_value, store_part(m_mo));
110 }
111
112 void commit()
113 {
114 m_value = m_atomic.load(load_part(m_mo));
115 }
116};
117
118template <typename T>
119QAtomicScopedValueRollback(QBasicAtomicPointer<T> &)
120 -> QAtomicScopedValueRollback<T*>;
121template <typename T>
122QAtomicScopedValueRollback(QBasicAtomicPointer<T> &, std::memory_order)
123 -> QAtomicScopedValueRollback<T*>;
124
126
127#endif // QATOMICASCOPEDVALUEROLLBACK_H
Q_NODISCARD_CTOR constexpr QAtomicScopedValueRollback(QBasicAtomicPointer< std::remove_pointer_t< T > > &var, T value, std::memory_order mo=std::memory_order_seq_cst)
Q_NODISCARD_CTOR constexpr QAtomicScopedValueRollback(std::atomic< T > &var, T value, std::memory_order mo=std::memory_order_seq_cst)
Q_NODISCARD_CTOR constexpr QAtomicScopedValueRollback(QBasicAtomicInteger< T > &var, std::memory_order mo=std::memory_order_seq_cst)
Q_NODISCARD_CTOR constexpr QAtomicScopedValueRollback(std::atomic< T > &var, std::memory_order mo=std::memory_order_seq_cst)
Q_NODISCARD_CTOR constexpr QAtomicScopedValueRollback(QBasicAtomicInteger< T > &var, T value, std::memory_order mo=std::memory_order_seq_cst)
Q_NODISCARD_CTOR constexpr QAtomicScopedValueRollback(QBasicAtomicPointer< std::remove_pointer_t< T > > &var, std::memory_order mo=std::memory_order_seq_cst)
p1 load("image.bmp")
auto mo
[7]
Combined button and popup list for selecting options.
QAtomicScopedValueRollback(QBasicAtomicPointer< T > &) -> QAtomicScopedValueRollback< T * >
#define Q_NODISCARD_CTOR
EGLOutputLayerEXT EGLint EGLAttrib value
[5]