32#ifndef FENNEC_THREADING_ATOMIC_H
33#define FENNEC_THREADING_ATOMIC_H
35#include <fennec/threading/detail/_atomic.h>
43using ::memory_order_relaxed;
44using ::memory_order_consume;
45using ::memory_order_acquire;
46using ::memory_order_release;
47using ::memory_order_acq_rel;
48using ::memory_order_seq_cst;
58 static_assert(is_integral_v<T>,
"fennec::atomic not defined for the provided type. Default implementation"
59 "only supports integral types.");
76 : _value(static_cast<T>(0)) {
84 constexpr atomic(
const T value) noexcept
125 void store(
const T x, memory_order order = memory_order_seq_cst)
noexcept {
126 ::atomic_store_explicit(&_value, x, order);
135 void store(
const T x, memory_order order = memory_order_seq_cst)
volatile noexcept {
136 ::atomic_store_explicit(&_value, x, order);
145 T
load(memory_order order = memory_order_seq_cst)
const noexcept {
146 return ::atomic_load_explicit(&_value, order);
156 T
load(memory_order order = memory_order_seq_cst)
const volatile noexcept {
157 return ::atomic_load_explicit(&_value, order);
163 operator T() const noexcept {
171 operator T() const volatile noexcept {
182 T
exchange(
const T x, memory_order order = memory_order_seq_cst)
noexcept {
183 return ::atomic_exchange_explicit(&_value, x, order);
194 T
exchange(
const T x, memory_order order = memory_order_seq_cst)
volatile noexcept {
195 return ::atomic_exchange_explicit(&_value, x, order);
210 return ::atomic_compare_exchange_weak_explicit(&_value, &
exp, x, succ, fail);
224 return ::atomic_compare_exchange_weak_explicit(&_value, &
exp, x, succ, fail);
238 return ::atomic_compare_exchange_weak_explicit(&_value, &
exp, x, order, order);
254 return ::atomic_compare_exchange_weak_explicit(&_value, &
exp, x, order, order);
269 return ::atomic_compare_exchange_strong_explicit(&_value, &
exp, x, succ, fail);
283 return ::atomic_compare_exchange_strong_explicit(&_value, &
exp, x, succ, fail);
297 return ::atomic_compare_exchange_strong_explicit(&_value, &
exp, x, order, order);
313 return ::atomic_compare_exchange_strong_explicit(&_value, &
exp, x, order, order);
320 T fetch_add(
const T x, memory_order order = memory_order_seq_cst)
noexcept {
321 return ::atomic_fetch_add_explicit(&_value, x, order);
324 T fetch_add(
const T x, memory_order order = memory_order_seq_cst)
volatile noexcept {
325 return ::atomic_fetch_add_explicit(&_value, x, order);
328 T operator+=(
const T x)
noexcept {
329 return this->fetch_add(x) + x;
332 T operator+=(
const T x)
volatile noexcept {
333 return this->fetch_add(x) + x;
338 T operator++() noexcept {
339 return this->fetch_add(1) + 1;
342 T operator++() volatile noexcept {
343 return this->fetch_add(1) + 1;
346 T operator++(
int)
noexcept {
347 return this->fetch_add(1);
350 T operator++(
int)
volatile noexcept {
351 return this->fetch_add(1);
356 T fetch_sub(
const T x, memory_order order = memory_order_seq_cst)
noexcept {
357 return ::atomic_fetch_sub_explicit(&_value, x, order);
360 T fetch_sub(
const T x, memory_order order = memory_order_seq_cst)
volatile noexcept {
361 return ::atomic_fetch_sub_explicit(&_value, x, order);
364 T operator-=(
const T x)
noexcept {
365 return this->fetch_sub(x) - x;
368 T operator-=(
const T x)
volatile noexcept {
369 return this->fetch_sub(x) - x;
374 T operator--() noexcept {
375 return this->fetch_sub(1) - 1;
378 T operator--() volatile noexcept {
379 return this->fetch_sub(1) - 1;
382 T operator--(
int)
noexcept {
383 return this->fetch_sub(1);
386 T operator--(
int)
volatile noexcept {
387 return this->fetch_sub(1);
394 T fetch_and(
const T x, memory_order order = memory_order_seq_cst)
noexcept {
395 return ::atomic_fetch_and_explicit(&_value, x, order);
398 T fetch_and(
const T x, memory_order order = memory_order_seq_cst)
volatile noexcept {
399 return ::atomic_fetch_and_explicit(&_value, x, order);
402 T operator&=(
const T x)
noexcept {
403 return this->fetch_and(x) & x;
406 T operator&=(
const T x)
volatile noexcept {
407 return this->fetch_and(x) & x;
412 T fetch_or(
const T x, memory_order order = memory_order_seq_cst)
noexcept {
413 return ::atomic_fetch_or_explicit(&_value, x, order);
416 T fetch_or(
const T x, memory_order order = memory_order_seq_cst)
volatile noexcept {
417 return ::atomic_fetch_or_explicit(&_value, x, order);
420 T operator|=(
const T x)
noexcept {
421 return this->fetch_or(x) & x;
424 T operator|=(
const T x)
volatile noexcept {
425 return this->fetch_or(x) & x;
430 T fetch_xor(
const T x, memory_order order = memory_order_seq_cst)
noexcept {
431 return ::atomic_fetch_xor_explicit(&_value, x, order);
434 T fetch_xor(
const T x, memory_order order = memory_order_seq_cst)
volatile noexcept {
435 return ::atomic_fetch_xor_explicit(&_value, x, order);
438 T operator^=(
const T x)
noexcept {
439 return this->fetch_xor(x) & x;
442 T operator^=(
const T x)
volatile noexcept {
443 return this->fetch_xor(x) & x;
constexpr genType exp(genType x)
Returns the natural exponentiation of , i.e., .
Definition exponential.h:122
Wrapper for atomic variables.
Definition atomic.h:54
void store(const T x, memory_order order=memory_order_seq_cst) noexcept
Definition atomic.h:125
bool compare_exchange_strong(T &exp, T x, memory_order order=memory_order_seq_cst) noexcept
Definition atomic.h:296
bool compare_exchange_strong(T &exp, T x, memory_order order=memory_order_seq_cst) volatile noexcept
Atomically compares the value of the atomic object with non-atomic argument and performs atomic excha...
Definition atomic.h:312
bool compare_exchange_strong(T &exp, T x, memory_order succ, memory_order fail) noexcept
Definition atomic.h:268
bool compare_exchange_strong(T &exp, T x, memory_order succ, memory_order fail) volatile noexcept
Definition atomic.h:282
T load(memory_order order=memory_order_seq_cst) const volatile noexcept
Atomically obtains the value of the atomic object.
Definition atomic.h:156
constexpr atomic(const T value) noexcept
Value Constructor.
Definition atomic.h:84
void store(const T x, memory_order order=memory_order_seq_cst) volatile noexcept
Atomically replaces the value of the atomic object with a non-atomic argument.
Definition atomic.h:135
bool compare_exchange_weak(T &exp, T x, memory_order order=memory_order_seq_cst) volatile noexcept
Atomically compares the value of the atomic object with non-atomic argument and performs atomic excha...
Definition atomic.h:253
bool compare_exchange_weak(T &exp, T x, memory_order succ, memory_order fail) noexcept
Definition atomic.h:209
T exchange(const T x, memory_order order=memory_order_seq_cst) volatile noexcept
Atomically replaces the value of the atomic object and obtains the value held previously.
Definition atomic.h:194
T load(memory_order order=memory_order_seq_cst) const noexcept
Definition atomic.h:145
bool compare_exchange_weak(T &exp, T x, memory_order succ, memory_order fail) volatile noexcept
Definition atomic.h:223
T operator=(const T x) noexcept
Definition atomic.h:101
bool compare_exchange_weak(T &exp, T x, memory_order order=memory_order_seq_cst) noexcept
Definition atomic.h:237
T exchange(const T x, memory_order order=memory_order_seq_cst) noexcept
Definition atomic.h:182
constexpr atomic() noexcept
Default Constructor.
Definition atomic.h:75
T operator=(const T x) volatile noexcept
Stores a value into an atomic object.
Definition atomic.h:112