<atomic>

[added with C++11]


atomic · atomic<integral> · atomic<Ty *> · atomic_flag · atomic_integral · memory_order

atomic_int8_t · atomic_uint8_t · atomic_int16_t · atomic_uint16_t · atomic_int32_t · atomic_uint32_t · atomic_int64_t · atomic_uint64_t · atomic_int_least8_t · atomic_uint_least8_t · atomic_int_least16_t · atomic_uint_least16_t · atomic_int_least32_t · atomic_uint_least32_t · atomic_int_least64_t · atomic_uint_least64_t · atomic_int_fast8_t · atomic_uint_fast8_t · atomic_int_fast16_t · atomic_uint_fast16_t · atomic_int_fast32_t · atomic_uint_fast32_t · atomic_int_fast64_t · atomic_uint_fast64_t · atomic_intptr_t · atomic_uintptr_t · atomic_size_t · atomic_ptrdiff_t · atomic_intmax_t · atomic_uintmax_t

atomic_compare_exchange_strong · atomic_compare_exchange_strong_explicit · atomic_compare_exchange_weak · atomic_compare_exchange_weak_explicit · atomic_exchange · atomic_exchange_explicit · atomic_fetch_add · atomic_fetch_add_explicit · atomic_fetch_and · atomic_fetch_and_explicit · atomic_fetch_or · atomic_fetch_or_explicit · atomic_fetch_sub · atomic_fetch_sub_explicit · atomic_fetch_xor · atomic_fetch_xor_explicit · atomic_flag_clear · atomic_flag_clear_explicit · atomic_flag_test_and_set · atomic_flag_test_and_set_explicit · atomic_init · atomic_is_lock_free · atomic_load · atomic_load_explicit · atomic_signal_fence · atomic_store · atomic_store_explicit · atomic_thread_fence · kill_dependency

ATOMIC_BOOL_LOCK_FREE · ATOMIC_CHAR_LOCK_FREE · ATOMIC_CHAR16_T_LOCK_FREE · ATOMIC_CHAR32_T_LOCK_FREE · ATOMIC_FLAG_INIT · ATOMIC_INT_LOCK_FREE · ATOMIC_LLONG_LOCK_FREE · ATOMIC_LONG_LOCK_FREE · ATOMIC_POINTER_LOCK_FREE · ATOMIC_SHORT_LOCK_FREE · ATOMIC_VAR_INIT · ATOMIC_WCHAR_T_LOCK_FREE


Include the standard header <atomic> to define several classes and template classes for defining types that support atomic operations. An atomic operation has two key properties:

These two properties, in conjunction with the inter-thread happens before relationship in the language definition, allow expert programmers to write algorithms that correctly manipulate an object from multiple threads without mutex locks.

This documentation uses, but does not define, the terms consume operation, acquire operation, release operation, acquire fence, release fence, sequentially consistent, and read-modify-write operation. These terms are formally defined in the C++ standard in [intro.multithread] and [atomics.fences] which also formalize their interaction with the C++ memory model.

On some platforms it might not be possible to efficiently implement atomic operations for some types without mutex locks. An atomic type is lock free if no atomic operations on that type use locks.

The class atomic_flag provides a minimal atomic type that holds a boolean flag. Its operations are always lock free.

The template class atomic<Ty> stores an object of its argument type Ty and provides atomic access to that stored value. It can be instantiated with any type that can be copied with memcpy and tested for equality with memcmp. In particular, it can be used with user-defined types that meet these requirements and, in many cases, floating-point types. The template also has a set of specializations for integral types and a partial specialization for pointers. These specializations provide additional operations that are not available through the general template:

Each atomic<integral> type has a corresponding macro that can be used in an if directive to determine at compile time whether operations on that type are lock free. If the value of the macro is zero, operations on the type are not lock free. If the value is 1, operations may be lock free, and a runtime check is needed. If the value is 2, operations are lock free. The function atomic_is_lock_free can be used to determine at runtime whether operations on the type are lock free.

For each of the integral types except bool there is a corresponding named atomic type that manages an object of that integral type. The managed type for each atomic_integral type is:

Each atomic_integral type has the same set of member functions as the corresponding instantiation of atomic<Ty> and can be passed to any of the non-member atomic functions.

There are typedef names for specializations of the atomic template for some of the types defined in the header <inttypes.h>:

There are also non-member atomic functions for all of the operations provided by the various atomic<Ty> templates. In the descriptions of each of these functions, a-type refers to any of the atomic types and m-type refers to the corresponding managed type. These functions are divided into three groups:

The managed type of any atomic type is the type of the data object that it manages. For instantiations of atomic<Ty> the managed type is Ty. For the atomic_integral types it is the corresponding integral type.

To create a fence, use the function atomic_thread_fence or the function atomic_signal_fence.

Some platforms support data dependency analysis. For those platforms, consider using the memory_order option memory_order_consume and the template function kill_dependency.

namespace std {
        // ENUMERATION TYPES
typedef enum memory_order {
    memory_order_relaxed,
    memory_order_consume,
    memory_order_acquire,
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst,
} memory_order;

        // TEMPLATE CLASS atomic
template<class Ty>
    struct atomic;
template<class Ty>
    struct atomic<Ty *>;
template<>
    struct atomic<char>;
template<>
    struct atomic<signed char>;
template<>
    struct atomic<unsigned char>;
template<>
    struct atomic<char16_t>;
template<>
    struct atomic<char32_t>;
template<>
    struct atomic<wchar_t>;
template<>
    struct atomic<short>;
template<>
    struct atomic<unsigned short>;
template<>
    struct atomic<int>;
template<>
    struct atomic<unsigned int>;
template<>
    struct atomic<long>;
template<>
    struct atomic<unsigned long>;
template<>
    struct atomic<long long>;
template<>
    struct atomic<unsigned long long>;

        // ATOMIC TYPEDEFS
typedef atomic<int8_t> atomic_int8_t;
typedef atomic<uint8_t> atomic_uint8_t;
typedef atomic<int16_t> atomic_int16_t;
typedef atomic<uint16_t> atomic_uint16_t;
typedef atomic<int32_t> atomic_int32_t;
typedef atomic<uint32_t> atomic_uint32_t;
typedef atomic<int64_t> atomic_int64_t;
typedef atomic<uint64_t> atomic_uint64_t;

typedef atomic<int_least8_t> atomic_int_least8_t;
typedef atomic<uint_least8_t> atomic_uint_least8_t;
typedef atomic<int_least16_t> atomic_int_least16_t;
typedef atomic<uint_least16_t> atomic_uint_least16_t;
typedef atomic<int_least32_t> atomic_int_least32_t;
typedef atomic<uint_least32_t> atomic_uint_least32_t;
typedef atomic<int_least64_t> atomic_int_least64_t;
typedef atomic<uint_least64_t> atomic_uint_least64_t;

typedef atomic<int_fast8_t> atomic_int_fast8_t;
typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
typedef atomic<int_fast16_t> atomic_int_fast16_t;
typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
typedef atomic<int_fast32_t> atomic_int_fast32_t;
typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
typedef atomic<int_fast64_t> atomic_int_fast64_t;
typedef atomic<uint_fast64_t> atomic_uint_fast64_t;

typedef atomic<intptr_t> atomic_intptr_t;
typedef atomic<uintptr_t> atomic_uintptr_t;
typedef atomic<size_t> atomic_size_t;
typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
typedef atomic<intmax_t> atomic_intmax_t;
typedef atomic<uintmax_t> atomic_uintmax_t;

        // TEMPLATE FUNCTIONS
template<class Ty>
    Ty kill_dependency(Ty t) noexcept;

        // MACROS
#define ATOMIC_FLAG_INIT initializer
#define ATOMIC_VAR_INIT initializer

#define ATOMIC_BOOL_LOCK_FREE integer-value
#define ATOMIC_CHAR_LOCK_FREE integer-value
#define ATOMIC_CHAR16_T_LOCK_FREE integer-value
#define ATOMIC_CHAR32_T_LOCK_FREE integer-value
#define ATOMIC_WCHAR_T_LOCK_FREE integer-value
#define ATOMIC_SHORT_LOCK_FREE integer-value
#define ATOMIC_INT_LOCK_FREE integer-value
#define ATOMIC_LONG_LOCK_FREE integer-value
#define ATOMIC_LLONG_LOCK_FREE integer-value
#define ATOMIC_POINTER_LOCK_FREE integer-value

        // STRUCT atomic_flag
typedef struct atomic_flag {
    ...
    } atomic_flag;
bool atomic_flag_test_and_set(volatile atomic_flag *) noexcept;
bool atomic_flag_test_and_set(atomic_flag *) noexcept;
bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order) noexcept;
bool atomic_flag_test_and_set_explicit(atomic_flag *, memory_order) noexcept;
bool atomic_flag_clear(volatile atomic_flag *) noexcept;
bool atomic_flag_clear(atomic_flag *) noexcept;
bool atomic_flag_clear_explicit(volatile atomic_flag *, memory_order) noexcept;
bool atomic_flag_clear_explicit(atomic_flag *, memory_order) noexcept;

        // GENERAL-PURPOSE ATOMIC TYPES
typedef struct atomic_char {
    ...
    } atomic_char;
typedef struct atomic_schar {
    ...
    } atomic_schar;
typedef struct atomic_uchar {
    ...
    } atomic_uchar;
typedef struct atomic_char16_t {
    ...
    } atomic_char16_t;
typedef struct atomic_char32_t {
    ...
    } atomic_char32_t;
typedef struct atomic_wchar_t {
    ...
    } atomic_wchar_t;
typedef struct atomic_short {
    ...
    } atomic_short;
typedef struct atomic_ushort {
    ...
    } atomic_ushort;
typedef struct atomic_int {
    ...
    } atomic_int;
typedef struct atomic_uint {
    ...
    } atomic_uint;
typedef struct atomic_long {
    ...
    } atomic_long;
typedef struct atomic_ulong {
    ...
    } atomic_ulong;
typedef struct atomic_llong {
    ...
    } atomic_llong;
typedef struct atomic_ullong {
    ...
    } atomic_ullong;

        // GENERAL OPERATIONS
template<class Ty>
    bool atomic_is_lock_free(const volatile a-type *) noexcept;
template<class Ty>
    bool atomic_is_lock_free(volatile a-type *) noexcept;

template<class Ty>
    bool atomic_init(volatile a-type *, Ty) noexcept;
template<class Ty>
    bool atomic_init(a-type *, Ty) noexcept;

template<class Ty>
    void atomic_store(volatile a-type *, Ty) noexcept;
template<class Ty>
    void atomic_store(a-type *, Ty) noexcept;

template<class Ty>
    void atomic_store_explicit(volatile a-type *, Ty, memory_order) noexcept;
template<class Ty>
    void atomic_store_explicit(a-type *, Ty, memory_order) noexcept;

template<class Ty>
    Ty atomic_load(const volatile a-type *) noexcept;
template<class Ty>
    Ty atomic_load(const a-type *) noexcept;

template<class Ty>
    Ty atomic_load_explicit(const volatile a-type *, memory_order) noexcept;
template<class Ty>
    Ty atomic_load_explicit(const a-type *, memory_order) noexcept;

template<class Ty>
    Ty atomic_exchange(const volatile a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_exchange(const a-type *, Ty) noexcept;

template<class Ty>
    Ty atomic_exchange_explicit(const volatile a-type *, Ty, memory_order) noexcept;
template<class Ty>
    Ty atomic_exchange_explicit(const a-type *, Ty, memory_order) noexcept;

template<class Ty>
    bool atomic_compare_exchange_weak(volatile a-type *, Ty *, Ty) noexcept;
template<class Ty>
    bool atomic_compare_exchange_weak(a-type *, Ty *, Ty) noexcept;
template<class Ty>
    bool atomic_compare_exchange_weak_explicit(volatile a-type *, Ty *, Ty,
    memory_order, memory_order) noexcept;
template<class Ty>
    bool atomic_compare_exchange_weak_explicit(a-type *, Ty *, Ty,
    memory_order, memory_order) noexcept;
template<class Ty>
    bool atomic_compare_exchange_strong(volatile a-type *, Ty *, Ty) noexcept;
template<class Ty>
    bool atomic_compare_exchange_strong(a-type *, Ty *, Ty) noexcept;
template<class Ty>
    bool atomic_compare_exchange_strong_explicit(volatile a-type *, Ty *, Ty,
    memory_order, memory_order) noexcept;
template<class Ty>
    bool atomic_compare_exchange_strong_explicit(a-type *, Ty *, Ty,
    memory_order, memory_order) noexcept;

        // ARITHMETIC OPERATIONS
template<class Ty>
    Ty atomic_fetch_add(volatile a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_add(a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_add_explicit(volatile a-type *, Ty, memory_order) noexcept;
template<class Ty>
    Ty atomic_fetch_add_explicit(a-type *, Ty, memory_order) noexcept;
template<class Ty>
    Ty atomic_fetch_sub(volatile a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_sub(a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_sub_explicit(volatile a-type *, Ty, memory_order) noexcept;
template<class Ty>
    Ty atomic_fetch_sub_explicit(a-type *, Ty, memory_order) noexcept;

        // LOGICAL OPERATIONS
template<class Ty>
    Ty atomic_fetch_and(volatile a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_and(a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_and_explicit(volatile a-type *, Ty, memory_order) noexcept;
template<class Ty>
    Ty atomic_fetch_and_explicit(a-type *, Ty, memory_order) noexcept;
template<class Ty>
    Ty atomic_fetch_or(volatile a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_or(a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_or_explicit(volatile a-type *, Ty, memory_order) noexcept;
template<class Ty>
    Ty atomic_fetch_or_explicit(a-type *, Ty, memory_order) noexcept;
template<class Ty>
    Ty atomic_fetch_xor(volatile a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_xor(a-type *, Ty) noexcept;
template<class Ty>
    Ty atomic_fetch_xor_explicit(volatile a-type *, Ty, memory_order) noexcept;
template<class Ty>
    Ty atomic_fetch_xor_explicit(a-type *, Ty, memory_order) noexcept;

        // FENCES
extern "C" void atomic_thread_fence(memory_order) noexcept;
extern "C" void atomic_signal_fence(memory_order) noexcept;
}   // namespace std

atomic


atomic · compare_exchange_strong · compare_exchange_weak · exchange · is_lock_free · load · operator Ty · operator= · store


template<class Ty>
    struct atomic {
    atomic() = default;
    constexpr atomic(Ty);
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    atomic& operator=(const atomic&) = delete;

    Ty operator=(Ty) volatile noexcept;
    Ty operator=(Ty) noexcept;
    operator Ty() const volatile noexcept;
    operator Ty() const noexcept;

    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;

    void store(Ty, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(Ty, memory_order = memory_order_seq_cst) noexcept;
    Ty load(memory_order = memory_order_seq_cst) const volatile noexcept;
    Ty load(memory_order = memory_order_seq_cst) const noexcept;
    Ty exchange(Ty, memory_order = memory_order_seq_cst) volatile noexcept;
    Ty exchange(Ty, memory_order = memory_order_seq_cst) noexcept;

    bool compare_exchange_weak(Ty&, Ty,
        memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(Ty&, Ty,
        memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(Ty&, Ty,
        memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(Ty&, Ty,
        memory_order, memory_order) noexcept;
    bool compare_exchange_strong(Ty&, Ty,
        memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(Ty&, Ty,
        memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(Ty&, Ty,
        memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(Ty&, Ty,
        memory_order, memory_order) noexcept;
};

The template class describes an object that performs atomic operations on a stored value of type Ty. There are specializations atomic<integral> for the built-in integral types and a partial specialization atomic<Ty *> for pointer types. This template is used for all other types.

The type Ty must be trivially copyable, that is, copying its bytes with memcpy must produce a valid Ty object that compares equal to the original object. Also, the compare_exchange_weak and compare_exchange_strong member functions use memcmp to determine whether two Ty values are equal; if Ty defines its own operator== these functions will not use it.

The member functions of atomic use memcpy to copy values of Ty.

Objects of type atomic<Ty> can be passed to any of the general operations.

atomic::atomic

atomic<Ty>::atomic() = default;
constexpr atomic<Ty>::atomic(Ty val) noexcept;
atomic<Ty>::atomic(const atomic&) = delete;

atomic<integral>::atomic<integral>() = default;
constexpr atomic<integral>::atomic<integral>(integral val) noexcept;
atomic<integral>::atomic<integral>(const atomic<integral>&) = delete;

atomic<Ty *>::atomic<Ty *>() = default;
constexpr atomic<Ty *>::atomic<Ty *>(Ty *) noexcept;
atomic<Ty *>::atomic<Ty *>(const atomic<Ty *>&) = delete;

atomic_integral::atomic_integral() = default;
constexpr atomic_integral::atomic_integral(m-type) noexcept;
atomic_integral::atomic_integral(const atomic_integral&) = delete;

Atomic objects cannot be copied and they cannot be moved. They can be initialized with aggregate initialization and with a constructor:

atomic<int> ai0 = { 0 };
atomic<int> ai1 = ATOMIC_VAR_INIT(0);
atomic<int> ai2(0);

In this implementation, when a compiler does not support =delete or =default, objects that are instantiations of atomic<Ty> can be initialized only by the contructor that takes an argument of type Ty and not with aggregate initialization; atomic_integral objects can be initialized only with aggregate initialization.

atomic::compare_exchange_strong

bool atomic<Ty>::compare_exchange_strong(
    Ty& exp, Ty val, memory_order order = memory_order_seq_cst) volatile noexcept;
bool atomic<Ty>::compare_exchange_strong(
    Ty& exp, Ty val, memory_order order = memory_order_seq_cst) noexcept;
bool atomic<Ty>::compare_exchange_strong(
    Ty& exp, Ty val, memory_order order1, memory_order order2) volatile noexcept;
bool atomic<Ty>::compare_exchange_strong(
    Ty& exp, Ty val, memory_order order1, memory_order order2) noexcept;

bool atomic<integral>::compare_exchange_strong(
    integral& exp, integral val, memory_order order = memory_order_seq_cst) volatile noexcept;
bool atomic<integral>::compare_exchange_strong(
    integral& exp, integral val, memory_order order = memory_order_seq_cst) noexcept;
bool atomic<integral>::compare_exchange_strong(
    integral& exp, integral val, memory_order order1, memory_order order2) volatile noexcept;
bool atomic<integral>::compare_exchange_strong(
    integral& exp, integral val, memory_order order1, memory_order order2) noexcept;

bool atomic<Ty *>::compare_exchange_strong(
    Ty *& exp, Ty *val, memory_order order = memory_order_seq_cst) volatile noexcept;
bool atomic<Ty *>::compare_exchange_strong(
    Ty *& exp, Ty *val, memory_order order = memory_order_seq_cst) noexcept;
bool atomic<Ty *>::compare_exchange_strong(
    Ty *& exp, Ty *val, memory_order order1, memory_order order2) volatile noexcept;
bool atomic<Ty *>::compare_exchange_strong(
    Ty *& exp, Ty *val, memory_order order1, memory_order order2) noexcept;

bool atomic_integral::compare_exchange_strong(
    m-type& exp, m-type val, memory_order order = memory_order_seq_cst) volatile noexcept;
bool atomic_integral::compare_exchange_strong(
    m-type& exp, m-type val, memory_order order = memory_order_seq_cst) noexcept;
bool atomic_integral::compare_exchange_strong(
    m-type& exp, m-type val, memory_order order1, memory_order order2) volatile noexcept;
bool atomic_integral::compare_exchange_strong(
    m-type& exp, m-type val, memory_order order1, memory_order order2) noexcept;

The member functions that take one memory_order argument perform an atomic compare and exchange operation on this, with order1 equal to order and order2 equal to memory_order_acquire if order is memory_order_acq_rel, memory_order_relaxed if order is memory_order_release, and order otherwise. They return the result of the operation.

The member functions that take two memory_order arguments perform an atomic compare and exchange operation on this and return the result. The value of order2 should not be memory_order_release or memory_order_acq_rel, nor should it be stronger than the value of order1.

atomic::compare_exchange_weak

bool atomic<Ty>::compare_exchange_weak(
    Ty& exp, Ty val, memory_order order = memory_order_seq_cst) volatile noexcept;
bool atomic<Ty>::compare_exchange_weak(
    Ty& exp, Ty val, memory_order order = memory_order_seq_cst) noexcept;
bool atomic<Ty>::compare_exchange_weak(
    Ty& exp, Ty val, memory_order order1, memory_order order2) volatile noexcept;
bool atomic<Ty>::compare_exchange_weak(
    Ty& exp, Ty val, memory_order order1, memory_order order2) noexcept;

bool atomic<integral>::compare_exchange_weak(
    integral& exp, integral val, memory_order order = memory_order_seq_cst) volatile noexcept;
bool atomic<integral>::compare_exchange_weak(
    integral& exp, integral val, memory_order order = memory_order_seq_cst) noexcept;
bool atomic<integral>::compare_exchange_weak(
    integral& exp, integral val, memory_order order1, memory_order order2) volatile noexcept;
bool atomic<integral>::compare_exchange_weak(
    integral& exp, integral val, memory_order order1, memory_order order2) noexcept;

bool atomic<Ty *>::compare_exchange_weak(
    Ty *& exp, Ty *val, memory_order order = memory_order_seq_cst) volatile noexcept;
bool atomic<Ty *>::compare_exchange_weak(
    Ty *& exp, Ty *val, memory_order order = memory_order_seq_cst) noexcept;
bool atomic<Ty *>::compare_exchange_weak(
    Ty *& exp, Ty *val, memory_order order1, memory_order order2) volatile noexcept;
bool atomic<Ty *>::compare_exchange_weak(
    Ty *& exp, Ty *val, memory_order order1, memory_order order2) noexcept;

bool atomic_integral::compare_exchange_weak(
    m-type& exp, m-type val, memory_order order = memory_order_seq_cst) volatile noexcept;
bool atomic_integral::compare_exchange_weak(
    m-type& exp, m-type val, memory_order order = memory_order_seq_cst) noexcept;
bool atomic_integral::compare_exchange_weak(
    m-type& exp, m-type val, memory_order order1, memory_order order2) volatile noexcept;
bool atomic_integral::compare_exchange_weak(
    m-type& exp, m-type val, memory_order order1, memory_order order2) noexcept;

The member functions that take one memory_order argument perform a weak atomic compare and exchange operation on this, with order1 equal to order and order2 equal to memory_order_acquire if order is memory_order_acq_rel, memory_order_relaxed if order is memory_order_release, and order otherwise. They return the result of the operation.

The member functions that take two memory_order arguments perform a weak atomic compare and exchange operation on this and return the result. The value of order2 should not be memory_order_release or memory_order_acq_rel, nor should it be stronger than the value of order1.

atomic::exchange

Ty atomic<Ty>::exchange(
    Ty value, memory_order order = memory_order_seq_cst) volatile noexcept;
Ty atomic<Ty>::exchange(
    Ty value, memory_order order = memory_order_seq_cst) noexcept;

integral atomic<integral>::exchange(
    integral value, memory_order order = memory_order_seq_cst) volatile noexcept;
integral atomic<integral>::exchange(
    integral value, memory_order order = memory_order_seq_cst) noexcept;

Ty *atomic<Ty *>::exchange(
    Ty *value, memory_order order = memory_order_seq_cst) volatile noexcept;
Ty *atomic<Ty *>::exchange(
    Ty *value, memory_order order = memory_order_seq_cst) noexcept;

m-type atomic_integral::exchange(
    m-type value, memory_order order = memory_order_seq_cst) volatile noexcept;
m-type atomic_integral::exchange(
    m-type value, memory_order order = memory_order_seq_cst) noexcept;

The member functions atomically store value as the stored value in *this and return the stored value that *this held on entry. They apply the memory constraints specified by order, and are read-modify-write operations.

atomic::fetch_add

integral atomic<integral>::fetch_add(
    integral val, memory_order order = memory_order_seq_cst) volatile noexcept;
integral atomic<integral>::fetch_add(
    integral val, memory_order order = memory_order_seq_cst) noexcept;

Ty *atomic<Ty *>::fetch_add(
    ptrdiff_t val, memory_order order = memory_order_seq_cst) volatile noexcept;
Ty *atomic<Ty *>::fetch_add(
    ptrdiff_t val, memory_order order = memory_order_seq_cst) noexcept;

m-type atomic_integral::fetch_add(
    m-type val, memory_order order = memory_order_seq_cst) volatile noexcept;
m-type atomic_integral::fetch_add(
    m-type val, memory_order order = memory_order_seq_cst) noexcept;

The member functions return atomic_fetch_add_explicit(this, val, order) + val.

atomic::fetch_and

integral atomic<integral>::fetch_and(
    integral val, memory_order order = memory_order_seq_cst) volatile noexcept;
integral atomic<integral>::fetch_and(
    integral val, memory_order order = memory_order_seq_cst);

m-type atomic_integral::fetch_and(
    m-type val, memory_order order = memory_order_seq_cst) volatile;
m-type atomic_integral::fetch_and(
    m-type val, memory_order order = memory_order_seq_cst) noexcept;

The member functions return atomic_fetch_and_explicit(this, val, order) & val.

atomic::fetch_or

integral atomic<integral>::fetch_or(
    integral val, memory_order order = memory_order_seq_cst) volatile noexcept;
integral atomic<integral>::fetch_or(
    integral val, memory_order order = memory_order_seq_cst) noexcept;

m-type atomic_integral::fetch_or(
    m-type val, memory_order order = memory_order_seq_cst) volatile noexcept;
m-type atomic_integral::fetch_or(
    m-type val, memory_order order = memory_order_seq_cst) noexcept;

The member functions return atomic_fetch_or_explicit(this, val, order) | val.

atomic::fetch_sub

integral atomic<integral>::fetch_sub(
    integral val, memory_order order = memory_order_seq_cst) volatile noexcept;
integral atomic<integral>::fetch_sub(
    integral val, memory_order order = memory_order_seq_cst) noexcept;

Ty *atomic<Ty *>::fetch_sub(
    ptrdiff_t val, memory_order order = memory_order_seq_cst) volatile noexcept;
Ty *atomic<Ty *>::fetch_sub(
    ptrdiff_t val, memory_order order = memory_order_seq_cst) noexcept;

m-type atomic_integral::fetch_sub(
    m-type val, memory_order order = memory_order_seq_cst) volatile noexcept;
m-type atomic_integral::fetch_sub(
    m-type val, memory_order order = memory_order_seq_cst) noexcept;

The member functions return atomic_fetch_sub_explicit(this, val, order) - val.

atomic::fetch_xor

integral atomic<integral>::fetch_xor(
    integral val, memory_order order = memory_order_seq_cst) volatile noexcept;
integral atomic<integral>::fetch_xor(
    integral val, memory_order order = memory_order_seq_cst) noexcept;

m-type atomic_integral::fetch_xor(
    m-type val, memory_order order = memory_order_seq_cst) volatile noexcept;
m-type atomic_integral::fetch_xor(
    m-type val, memory_order order = memory_order_seq_cst) noexcept;

The member functions return atomic_fetch_xor_explicit(this, val, order) ^ val.

atomic::is_lock_free

bool is_lock_free() const volatile noexcept;
bool is_lock_free() const noexcept;

The member functions return atomic_is_lock_free(this).

atomic::load

Ty atomic<Ty>::load(memory_order order = memory_order_seq_cst) const volatile noexcept;
Ty atomic<Ty>::load(memory_order order = memory_order_seq_cst) const noexcept;

integral atomic<integral>::load(memory_order order = memory_order_seq_cst) const volatile noexcept;
integral atomic<integral>::load(memory_order order = memory_order_seq_cst) const noexcept;

Ty *atomic<Ty *>::load(memory_order order = memory_order_seq_cst) const volatile noexcept;
Ty *atomic<Ty *>::load(memory_order order = memory_order_seq_cst) const noexcept;

m-type atomic_integral::load(memory_order order = memory_order_seq_cst) const volatile noexcept;
m-type atomic_integral::load(memory_order order = memory_order_seq_cst) const noexcept;

The member functions atomically read the stored value of *this and return the result. They apply the memory constraints specified by order. The value of order should not be memory_order_release or memory_order_acq_rel.

atomic::operator Ty

atomic<Ty>::operator Ty() const volatile noexcept;
atomic<Ty>::operator Ty() const noexcept;

atomic<integral>::operator integral() const volatile noexcept;
atomic<integral>::operator integral() const noexcept;

atomic<Ty *>::operator Ty *() const volatile noexcept;
atomic<Ty *>::operator Ty *() const noexcept;

atomic_integral::operator m-type() const volatile noexcept;
atomic_integral::operator m-type() const noexcept;

The member operators return load(memory_order_seq_cst).

atomic::operator=

Ty atomic<Ty>::operator=(Ty val) volatile noexcept;
Ty atomic<Ty>::operator=(Ty val) noexcept;

integral atomic<integral>::operator=(integral val) volatile noexcept;
integral atomic<integral>::operator=(integral val) noexcept;

Ty *atomic<Ty *>::operator=(Ty *val) volatile noexcept;
Ty *atomic<Ty *>::operator=(Ty *val) noexcept;

m-type atomic_integral::operator=(m-type val) volatile noexcept;
m-type atomic_integral::operator=(m-type val) noexcept;

The member operators call store(val) and return val.

atomic::operator++

atomic<integral>::operator++(int) volatile noexcept;
atomic<integral>::operator++(int) noexcept;

atomic<Ty *>::operator++(int) volatile noexcept;
atomic<Ty *>::operator++(int) noexcept;

atomic_integral::operator++(int) volatile noexcept;
atomic_integral::operator++(int) noexcept;

atomic<integral>::operator++() volatile noexcept;
atomic<integral>::operator++() noexcept;

atomic<Ty *>::operator++() volatile noexcept;
atomic<Ty *>::operator++() noexcept;

atomic_integral::operator++() volatile noexcept;
atomic_integral::operator++() noexcept;

The first six member operators return atomic_fetch_add_explicit(this, 1, memory_order_seq_cst). The last six member operators return atomic_fetch_add_explicit(this, 1, memory_order_seq_cst) + 1.

atomic::operator+=

atomic<integral>::operator+=(integral val) volatile noexcept;
atomic<integral>::operator+=(integral val) noexcept;

atomic<Ty *>::operator+=(ptrdiff_t val) volatile noexcept;
atomic<Ty *>::operator+=(ptrdiff_t val) noexcept;

atomic_integral::operator+=(m-type val) volatile noexcept;
atomic_integral::operator+=(m-type val) noexcept;

The member operators return atomic_fetch_add_explicit(this, val, memory_order_seq_cst) + val.

atomic::operator--

atomic<integral>::operator--(int) volatile noexcept;
atomic<integral>::operator--(int) noexcept;

atomic<Ty *>::operator--(int) volatile noexcept;
atomic<Ty *>::operator--(int) noexcept;

atomic_integral::operator--(int) volatile noexcept;
atomic_integral::operator--(int) noexcept;

atomic<integral>::operator--() volatile noexcept;
atomic<integral>::operator--() noexcept;

atomic<Ty *>::operator--() volatile noexcept;
atomic<Ty *>::operator--() noexcept;

atomic_integral::operator--() volatile noexcept;
atomic_integral::operator--() noexcept;

The first six member operators return atomic_fetch_sub_explicit(this, 1, memory_order_seq_cst). The last six member operators return atomic_fetch_sub_explicit(this, 1, memory_order_seq_cst) - 1.

atomic::operator-=

atomic<integral>::operator-=(integral val) volatile noexcept;
atomic<integral>::operator-=(integral val) noexcept;

atomic<Ty *>::operator-=(ptrdiff_t val) volatile noexcept;
atomic<Ty *>::operator-=(ptrdiff_t val) noexcept;

atomic_integral::operator-=(m-type val) volatile noexcept;
atomic_integral::operator-=(m-type val) noexcept;

The member operators return atomic_fetch_sub_explicit(this, val, memory_order_seq_cst) - val.

atomic::operator&=

atomic<integral>::operator&=(integral val) volatile noexcept;
atomic<integral>::operator&=(integral val) noexcept;

atomic_integral::operator&=(m-type val) volatile noexcept;
atomic_integral::operator&=(m-type val) noexcept;

The member operators return atomic_fetch_and_explicit(this, val, memory_order_seq_cst) & val.

atomic::operator|=

atomic<integral>::operator|=(integral val) volatile noexcept;
atomic<integral>::operator|=(integral val) noexcept;

atomic_integral::operator|=(m-type val) volatile noexcept;
atomic_integral::operator|=(m-type val) noexcept;

The member operators return atomic_fetch_or_explicit(this, val, memory_order_seq_cst) | val.

atomic::operator^=

atomic<integral>::operator^=(integral val) volatile noexcept;
atomic<integral>::operator^=(integral val) noexcept;

atomic_integral::operator^=(m-type val) volatile noexcept;
atomic_integral::operator^=(m-type val) noexcept;

The member operators return atomic_fetch_xor_explicit(this, val, memory_order_seq_cst) ^ val.

atomic::store

void atomic<Ty>::store(
    Ty val, memory_order order = memory_order_seq_cst) volatile noexcept;
void atomic<Ty>::store(
    Ty val, memory_order order = memory_order_seq_cst) noexcept;

void atomic<integral>::store(
    integral val, memory_order order = memory_order_seq_cst) volatile noexcept;
void atomic<integral>::store(
    integral val, memory_order order = memory_order_seq_cst) noexcept;

void atomic<Ty *>::store(
    Ty *val, memory_order order = memory_order_seq_cst) volatile noexcept;
void atomic<Ty *>::store(
    Ty *val, memory_order order = memory_order_seq_cst) noexcept;

void atomic_integral::store(
    m-type val, memory_order order = memory_order_seq_cst) volatile noexcept;
void atomic_integral::store(
    m-type val, memory_order order = memory_order_seq_cst) noexcept;

The member functions atomically store val as the stored value in *this. They apply the memory constraints specified by order. The value of order should not be memory_order_consume, memory_order_acquire, or memory_order_acq_rel.

atomic<integral>


atomic<integral> · compare_exchange_strong · compare_exchange_weak · exchange · fetch_add · fetch_and · fetch_or · fetch_sub · fetch_xor · is_lock_free · load · operator integral · operator= · operator++ · operator+= · operator-- · operator-= · operator&= · operator|= · operator^= · store


template<>
    struct atomic<integral> {
    atomic() = default;
    constexpr atomic(integral) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    atomic& operator=(const atomic&) = delete;

    integral operator=(integral) volatile noexcept;
    integral operator=(integral) noexcept;
    atomic& operator=(const atomic&) volatile = delete;
    atomic& operator=(const atomic&) = delete;

    integral operator=(integral) volatile noexcept;
    integral operator=(integral) noexcept;
    operator integral() const volatile noexcept;
    operator integral() const noexcept;

    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;

    void store(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(integral, memory_order = memory_order_seq_cst) noexcept;
    integral load(memory_order = memory_order_seq_cst) const volatile noexcept;
    integral load(memory_order = memory_order_seq_cst) const noexcept;
    integral exchange(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral exchange(integral, memory_order = memory_order_seq_cst) noexcept;

    bool compare_exchange_weak(integral&, integral,
        memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(integral&, integral,
        memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(integral&, integral,
        memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(integral&, integral,
        memory_order, memory_order) noexcept;
    bool compare_exchange_strong(integral&, integral,
        memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(integral&, integral,
        memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(integral&, integral,
        memory_order, memory_order) volatile;
    bool compare_exchange_strong(integral&, integral,
        memory_order, memory_order) noexcept;

    integral fetch_add(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_add(integral, memory_order = memory_order_seq_cst) noexcept;
    integral fetch_sub(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_sub(integral, memory_order = memory_order_seq_cst) noexcept;
    integral fetch_and(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_and(integral, memory_order = memory_order_seq_cst) noexcept;
    integral fetch_or(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_or(integral, memory_order = memory_order_seq_cst) noexcept;
    integral fetch_xor(integral, memory_order = memory_order_seq_cst) volatile noexcept;
    integral fetch_xor(integral, memory_order = memory_order_seq_cst) noexcept;

    integral operator++(int) volatile noexcept;
    integral operator++(int) noexcept;
    integral operator++() volatile noexcept;
    integral operator++() noexcept;
    integral operator+=(integral) volatile noexcept;
    integral operator+=(integral) noexcept;
    integral operator--(int) volatile noexcept;
    integral operator--(int) noexcept;
    integral operator--() volatile noexcept;
    integral operator--() noexcept;
    integral operator-=(integral) volatile noexcept;
    integral operator-=(integral) noexcept;
    integral operator&=(integral) volatile noexcept;
    integral operator&=(integral) noexcept;
    integral operator|=(integral) volatile noexcept;
    integral operator|=(integral) noexcept;
    integral operator^=(integral) volatile noexcept;
    integral operator^=(integral) noexcept;
};

For each of the integral types except bool there is a corresponding specialization of the template class atomic<Ty> instantiated with the integral type:

Objects of these types can be passed to any of the non-member atomic functions described earlier.

In this implementation the template specialization is derived from the corresponding atomic_integral type. For example, the specialization atomic<unsigned int> is derived from atomic_uint.

atomic<Ty *>


atomic<Ty *> · compare_exchange_strong · compare_exchange_weak · exchange · fetch_add · fetch_sub · is_lock_free · load · operator Ty * · operator= · operator++ · operator+= · operator-- · operator-= · store


template<class Ty>
     struct atomic<Ty *> {
    atomic() = default;
    constexpr atomic(Ty *) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    atomic& operator=(const atomic&) = delete;

    Ty *operator=(Ty *) volatile noexcept;
    Ty *operator=(Ty *) noexcept;
    operator Ty *() const volatile noexcept;
    operator Ty *() const noexcept;

    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;

    void store(Ty *, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(Ty *, memory_order = memory_order_seq_cst) noexcept;
    Ty *load(memory_order = memory_order_seq_cst) const volatile noexcept;
    Ty *load(memory_order = memory_order_seq_cst) const noexcept;
    Ty *exchange(Ty *, memory_order = memory_order_seq_cst) volatile noexcept;
    Ty *exchange(Ty *, memory_order = memory_order_seq_cst) noexcept;

    bool compare_exchange_weak(Ty *&, Ty *,
        memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(Ty *&, Ty *,
        memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(Ty *&, Ty *,
        memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(Ty *&, Ty *,
        memory_order, memory_order) noexcept;
    bool compare_exchange_strong(Ty *&, Ty *,
        memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(Ty *&, Ty *,
        memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(Ty *&, Ty *,
        memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(Ty *&, Ty *,
        memory_order, memory_order) noexcept;

    Ty *fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept;
    Ty *fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept;
    Ty *fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept;
    Ty *fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept noexcept;

    Ty *operator++(int) volatile noexcept;
    Ty *operator++(int) noexcept;
    Ty *operator++() volatile noexcept;
    Ty *operator++() noexcept;
    Ty *operator--(int) volatile noexcept;
    Ty *operator--(int) noexcept;
    Ty *operator--() volatile noexcept;
    Ty *operator--() noexcept;
    Ty *operator+=(ptrdiff_t) volatile noexcept;
    Ty *operator+=(ptrdiff_t) noexcept;
    Ty *operator-=(ptrdiff_t) volatile noexcept;
    Ty *operator-=(ptrdiff_t) noexcept;
};

The partial specialization describes an object that performs atomic operations on a stored value of type Ty *. Its arithmetic operations are a bit different from those in atomic<integral>: they take an argument of type ptrdiff_t and they adjust that argument according to the size of Ty to be consistent with ordinary address arithmetic.

Objects of any of these partial specializations can be passed to the general operations and the arithmetic operations.

ATOMIC_BOOL_LOCK_FREE

#define ATOMIC_BOOL_LOCK_FREE integer-value

The macro has a value that indicates whether the type atomic<bool> is lock free.

ATOMIC_CHAR_LOCK_FREE

#define ATOMIC_CHAR_LOCK_FREE integer-value

The macro has a value that indicates whether the types atomic_char, atomic_schar, and atomic_uchar are lock free.

ATOMIC_CHAR16_T_LOCK_FREE

#define ATOMIC_CHAR16_T_LOCK_FREE integer-value

The macro has a value that indicates whether the type atomic_char16_t is lock free.

ATOMIC_CHAR32_T_LOCK_FREE

#define ATOMIC_CHAR32_T_LOCK_FREE integer-value

The macro has a value that indicates whether the type atomic_char32_t is lock free.

atomic_compare_exchange_strong

template<class Ty>
    bool atomic_compare_exchange_strong(volatile a-type *atom, Ty *exp, Ty val) noexcept;
template<class Ty>
    bool atomic_compare_exchange_strong(a-type *atom, Ty *exp, Ty val) noexcept;

The template functions return atomic_compare_exchange_strong_explicit(atom, exp, val, memory_order_seq_cst, memory_order_seq_cst).

atomic_compare_exchange_strong_explicit

template<class Ty>
    bool atomic_compare_exchange_strong_explicit(volatile a-type *atom, Ty *exp, Ty val,
    memory_order order1, memory_order order2) noexcept;
template<class Ty>
    bool atomic_compare_exchange_strong_explicit(a-type *atom, Ty *exp, Ty val,
    memory_order order1, memory_order order2) noexcept;

The template functions perform an atomic compare and exchange operation on their arguments and return the result. The value of order2 should not be memory_order_release or memory_order_acq_rel, nor should it be stronger than the value of order1.

An atomic compare and exchange operation takes five arguments: an atom, which is a pointer to the object that the operation is applied to; a pointer or reference named exp that refers to a value; a value named val; and two memory order arguments, order1 and order2. The operation does the following, all atomically: it compares the value stored in the object pointed to by atom with the value pointed to by exp; if they are equal, it replaces the value stored in the object pointed to by atom with the value val with a read-modify-write operation and applies the memory order constraints specified by order1; if they are not equal, it replaces the value pointed to by exp with the value stored in the object pointed to by atom and applies the memory order constraints specified by order2. It returns the boolean value that was the result of the comparison.

atomic_compare_exchange_weak

template<class Ty>
    bool atomic_compare_exchange_weak(volatile a-type *atom, Ty *exp, Ty val) noexcept;
template<class Ty>
    bool atomic_compare_exchange_weak(a-type *atom, Ty *exp, Ty val) noexcept;

The template functions return atomic_compare_exchange_weak_explicit(atom, exp, val, memory_order_seq_cst, memory_order_seq_cst).

atomic_compare_exchange_weak_explicit

template<class Ty>
    bool atomic_compare_exchange_weak_explicit(volatile a-type *atom, Ty *exp, Ty val,
    memory_order order1, memory_order order2) noexcept;
template<class Ty>
    bool atomic_compare_exchange_weak_explicit(a-type *atom, Ty *exp, Ty val,
    memory_order order1, memory_order order2) noexcept;

The template functions perform a weak atomic compare and exchange operation on their arguments and return the result. The value of order2 should not be memory_order_release or memory_order_acq_rel, nor should it be stronger than the value of order1.

A weak atomic compare and exchange is an atomic compare and exchange operation that may return spuriously. If it returns true, the comparison succeeded and the success exchange was made; if it returns false, the comparison failed and the failure exchange may or may not have been made.

atomic_exchange

template<class Ty>
    Ty atomic_exchange(volatile a-type *atom, Ty value) noexcept;
template<class Ty>
    Ty atomic_exchange(a-type *atom, Ty value) noexcept;

The template functions return atomic_exchange_explicit(atom, value, memory_order_seq_cst).

atomic_exchange_explicit

template<class Ty>
    Ty atomic_exchange_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept;
template<class Ty>
    Ty atomic_exchange_explicit(a-type *atom, Ty value, memory_order order) noexcept;

The template functions atomically store value as the stored value in *atom and return the stored value that *atom held on entry. They apply the memory constraints specified by order, and are read-modify-write operations.

atomic_fetch_add

template<class Ty>
    Ty atomic_fetch_add(volatile a-type *atom, Ty value) noexcept;
template<class Ty>
    Ty atomic_fetch_add(a-type *atom, Ty value) noexcept;

The template functions return atomic_fetch_add_explicit(atom, value, memory_order_seq_cst).

atomic_fetch_add_explicit

template<class Ty>
    Ty atomic_fetch_add_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept;
template<class Ty>
    Ty atomic_fetch_add_explicit(a-type *atom, Ty value, memory_order order) noexcept;

The template functions atomically add value to the stored value held in *atom, store the result in *atom, and return the result. They apply the memory constraints specified by order, and are read-modify-write operations.

atomic_fetch_and

template<class Ty>
    Ty atomic_fetch_and(volatile a-type *atom, Ty value) noexcept;
template<class Ty>
    Ty atomic_fetch_and(a-type *atom, Ty value) noexcept;

The template functions return atomic_fetch_and_explicit(atom, value, memory_order_seq_cst).

atomic_fetch_and_explicit

template<class Ty>
    Ty atomic_fetch_and_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept;
template<class Ty>
    Ty atomic_fetch_and_explicit(a-type *atom, Ty value, memory_order order) noexcept;

The template functions atomically store into *atom the bitwise and of value and the stored value held in *atom and return the result. They apply the memory constraints specified by order, and are read-modify-write operations.

atomic_fetch_or

template<class Ty>
    Ty atomic_fetch_or(volatile a-type *atom, Ty value) noexcept;
template<class Ty>
    Ty atomic_fetch_or(a-type *atom, Ty value) noexcept;

The template functions return atomic_fetch_or_explicit(atom, value, memory_order_seq_cst).

atomic_fetch_or_explicit

template<class Ty>
    Ty atomic_fetch_or_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept;
template<class Ty>
    Ty atomic_fetch_or_explicit(a-type *atom, Ty value, memory_order order) noexcept;

The template functions atomically store into *atom the bitwise inclusive or of value and the stored value held in *atom and return the result. They apply the memory constraints specified by order, and are read-modify-write operations.

atomic_fetch_sub

template<class Ty>
    Ty atomic_fetch_sub(volatile a-type *atom, Ty value) noexcept;
template<class Ty>
    Ty atomic_fetch_sub(a-type *atom, Ty value) noexcept;

The template functions return atomic_fetch_sub_explicit(atom, value, memory_order_seq_cst).

atomic_fetch_sub_explicit

template<class Ty>
    Ty atomic_fetch_sub_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept;
template<class Ty>
    Ty atomic_fetch_sub_explicit(a-type *atom, Ty value, memory_order order) noexcept;

The template functions atomically subtract value from the stored value held in *atom, store the result in *atom, and return the result. They apply the memory constraints specified by order, and are read-modify-write operations.

When a-type is atomic_address, the argument value has type ptrdiff_t and the subtraction is done as if the stored pointer had type char *.

atomic_fetch_xor

template<class Ty>
    Ty atomic_fetch_xor(volatile a-type *atom, Ty value) noexcept;
template<class Ty>
    Ty atomic_fetch_xor(a-type *atom, Ty value) noexcept;

The template functions return atomic_fetch_xor_explicit(atom, value, memory_order_seq_cst).

atomic_fetch_xor_explicit

template<class Ty>
    Ty atomic_fetch_xor_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept;
template<class Ty>
    Ty atomic_fetch_xor_explicit(a-type *atom, Ty value, memory_order order) noexcept;

The template functions atomically store into *atom the bitwise exclusive or of value and the stored value held in *atom and return the result. They apply the memory constraints specified by order, and are read-modify-write operations.

atomic_flag


atomic_flag · clear · test_and_set


typef struct atomic_flag {
    atomic_flag() = default;
    atomic_flag(const atomic_flag&) = delete;
    atomic_flag& operator=(const atomic_flag&) volatile = delete;
    atomic_flag& operator=(const atomic_flag&) = delete;

    bool test_and_set(memory_order = memory_order_seq_cst) volatile noexcept;
    bool test_and_set(memory_order = memory_order_seq_cst) noexcept;
    void clear(memory_order = memory_order_seq_cst) volatile noexcept;
    void clear(memory_order = memory_order_seq_cst) noexcept;
} atomic_flag;

The class describes an object that atomically sets and clears a boolean flag. These operations are always lock free.

Objects of type atomic_flag can be passed to the non-member functions atomic_flag_clear, atomic_flag_clear_explicit, atomic_flag_test_and_set, and atomic_flag_test_and_set_explicit, and can be initialized with the value ATOMIC_FLAG_INIT.

atomic_flag::atomic_flag

atomic_flag() noexcept;

The constructor constructs an object that holds an unspecified value.

atomic_flag::clear

void clear(memory_order order = memory_order_seq_cst) volatile noexcept;
void clear(memory_order order = memory_order_seq_cst) noexcept;

The member functions call atomic_flag_clear_explicit(this, order).

atomic_flag::test_and_set

bool test_and_set(memory_order order = memory_order_seq_cst) volatile noexcept;
bool test_and_set(memory_order order = memory_order_seq_cst) noexcept;

The member functions return atomic_flag_test_and_set_explicit(this, order).

atomic_flag_clear

void atomic_flag_clear(volatile atomic_flag *atom) noexcept;
void atomic_flag_clear(atomic_flag *atom) noexcept;

The functions call atomic_flag_clear_explicit(atom, memory_order_seq_cst).

atomic_flag_clear_explicit

void atomic_flag_clear_explicit(volatile atomic_flag *atom, memory_order order) noexcept;
void atomic_flag_clear_explicit(atomic_flag *atom, memory_order order) noexcept;

The functions atomically set the flag stored in atom to false and apply the memory order constraints specified by order.

ATOMIC_FLAG_INIT

#define ATOMIC_FLAG_INIT initializer

The macro defines a value that can be used to statically initialize an object of type atomic_flag to its cleared state.

atomic_flag_test_and_set

bool atomic_flag_test_and_set(volatile atomic_flag *atom) noexcept;
bool atomic_flag_test_and_set(atomic_flag *atom) noexcept;

The functions return atomic_flag_test_and_set_explicit(atom, memory_order_seq_cst).

atomic_flag_test_and_set_explicit

bool atomic_flag_test_and_set_explicit(volatile atomic_flag *atom, memory_order order) noexcept;
bool atomic_flag_test_and_set_explicit(atomic_flag *atom, memory_order order) noexcept;

The functions atomically set the flag stored in atom to true and return the value that the flag had on entry. They apply the memory constraints specified by order, and are read-modify-write operations.

atomic_init

template<class Ty>
    bool atomic_init(volatile a-type *, Ty) noexcept;
template<class Ty>
    bool atomic_init(a-type *, Ty) noexcept;

The template functions set the value stored in atom to value. They are not atomic and not thread-safe.

atomic_integral


atomic_integral · compare_exchange_strong · compare_exchange_weak · exchange · fetch_add · fetch_and · fetch_or · fetch_sub · fetch_xor · is_lock_free · load · operator m-type · operator= · operator++ · operator+= · operator-- · operator-= · operator&= · operator|= · operator^= · store


typedef struct atomic_char { /* ... */ } atomic_char;
typedef struct atomic_schar { /* ... */ } atomic_schar;
typedef struct atomic_uchar { /* ... */ } atomic_uchar;
typedef struct atomic_char16_t { /* ... */ } atomic_char16_6;
typedef struct atomic_char32_t { /* ... */ } atomic_char32_t;
typedef struct atomic_wchar_t { /* ... */ } atomic_wchar_t;
typedef struct atomic_short { /* ... */ } atomic_short;
typedef struct atomic_ushort { /* ... */ } atomic_ushort;
typedef struct atomic_int { /* ... */ } atomic_int;
typedef struct atomic_uint { /* ... */ } atomic_uint;
typedef struct atomic_long { /* ... */ } atomic_long;
typedef struct atomic_ulong { /* ... */ } atomic_ulong;
typedef struct atomic_llong { /* ... */ } atomic_llong;
typedef struct atomic_ullong { /* ... */ } atomic_ullong;

typedef struct atomic_integral {
    atomic_integral() = default;
    constexpr atomic_integral(m-type) noexcept;
    atomic_integral(const atomic_integral&) = delete;
    atomic_integral& operator=(const atomic_integral&) volatile = delete;
    atomic_integral& operator=(const atomic_integral&) = delete;

    m-type operator=(m-type) volatile;
    m-type operator=(m-type) noexcept;
    operator m-type() const volatile noexcept;
    operator m-type() const noexcept;

    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;
    void store(m-type, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(m-type, memory_order = memory_order_seq_cst) noexcept;
    m-type load(memory_order = memory_order_seq_cst) const volatile noexcept;
    m-type load(memory_order = memory_order_seq_cst) const noexcept;
    m-type exchange(m-type, memory_order = memory_order_seq_cst) volatile noexcept;
    m-type exchange(m-type, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(m-type&, m-type,
        memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(m-type&, m-type,
        memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(m-type&, m-type,
        memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(m-type&, m-type,
        memory_order, memory_order) noexcept;
    bool compare_exchange_strong(m-type&, m-type,
        memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(m-type&, m-type,
        memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(m-type&, m-type,
        memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(m-type&, m-type,
        memory_order, memory_order) noexcept;

    m-type fetch_add(m-type, memory_order = memory_order_seq_cst) volatile noexcept;
    m-type fetch_add(m-type, memory_order = memory_order_seq_cst) noexcept;
    m-type fetch_sub(m-type, memory_order = memory_order_seq_cst) volatile noexcept;
    m-type fetch_sub(m-type, memory_order = memory_order_seq_cst) noexcept;
    m-type fetch_and(m-type, memory_order = memory_order_seq_cst) volatile noexcept;
    m-type fetch_and(m-type, memory_order = memory_order_seq_cst) noexcept;
    m-type fetch_or(m-type, memory_order = memory_order_seq_cst) volatile noexcept;
    m-type fetch_or(m-type, memory_order = memory_order_seq_cst) noexcept;
    m-type fetch_xor(m-type, memory_order = memory_order_seq_cst) volatile noexcept;
    m-type fetch_xor(m-type, memory_order = memory_order_seq_cst) noexcept;

    m-type operator++(int) volatile noexcept;
    m-type operator++(int) noexcept;
    m-type operator++() volatile noexcept;
    m-type operator++() noexcept;
    m-type operator--(int) volatile noexcept;
    m-type operator--(int) noexcept;
    m-type operator--() volatile noexcept;
    m-type operator--() noexcept;
    m-type operator+=(m-type) volatile noexcept;
    m-type operator+=(m-type) noexcept;
    m-type operator-=(m-type) volatile noexcept;
    m-type operator-=(m-type) noexcept;
    m-type operator&=(m-type) volatile noexcept;
    m-type operator&=(m-type) noexcept;
    m-type operator|=(m-type) volatile noexcept;
    m-type operator|=(m-type) noexcept;
    m-type operator^=(m-type) volatile noexcept;
    m-type operator^=(m-type) noexcept;
} atomic_integral;

The integral atomic types consist of all of the general-purpose atomic types except atomic_address and atomic_bool. Each integral atomic type describes an object that performs atomic operations on a stored value of its managed type.

Objects of these types can be passed to the general operations, the arithmetic operations, and the logical operations.

ATOMIC_INT_LOCK_FREE

#define ATOMIC_INT_LOCK_FREE integer-value

The macro has a value that indicates whether the types atomic_int and atomic_uint are lock free.

atomic_is_lock_free

template<class Ty>
    bool atomic_is_lock_free(const volatile a-type *atom) noexcept;
template<class Ty>
    bool atomic_is_lock_free(const a-type *atom) noexcept;

The template functions return true only if atomic operations on *atom are lock free.

ATOMIC_LLONG_LOCK_FREE

#define ATOMIC_LLONG_LOCK_FREE integer-value

The macro has a value that indicates whether the types atomic_llong and atomic_ullong are lock free.

atomic_load

Ty atomic_load(const volatile a-type *atom) noexcept;
Ty atomic_load(const a-type *atom) noexcept;

The functions return atomic_load_explicit(atom, memory_order_seq_cst).

atomic_load_explicit

Ty atomic_load_explicit(const volatile a-type *atom, memory_order order);
Ty atomic_load_explicit(const a-type *atom, memory_order order);

The functions atomically load the stored value held in *atom and return the result. They apply the memory constraints specified by order. The value of order should not be memory_order_release or memory_order_acq_rel.

ATOMIC_LONG_LOCK_FREE

#define ATOMIC_LONG_LOCK_FREE integer-value

The macro has a value that indicates whether the types atomic_long and atomic_ulong are lock free.

ATOMIC_POINTER_LOCK_FREE

#define ATOMIC_POINTER_LOCK_FREE integer-value

The macro has a value that indicates whether the type atomic<Ty *>, where Ty is any object type, is lock free.

ATOMIC_SHORT_LOCK_FREE

#define ATOMIC_SHORT_LOCK_FREE integer-value

The macro has a value that indicates whether the types atomic_short and atomic_ushort are lock free.

atomic_signal_fence

extern "C" void atomic_signal_fence(memory_order order) noexcept;

The function acts the same as atomic_thread_fence except that it establishes ordering requirements only between fences in the calling thread and in signal handlers executed in the same thread.

atomic_store

template<class Ty>
    void atomic_store(volatile a-type *atom, Ty value) noexcept;
template<class Ty>
    void atomic_store(Ty *atom, a-type value) noexcept;

The template functions call atomic_store_explicit(atom, value, memory_order_seq_cst).

atomic_store_explicit

template<class Ty>
    void atomic_store_explicit(volatile a-type *atom, Ty value, memory_order order) noexcept;
template<class Ty>
    void atomic_store_explicit(a-type *atom, Ty value, memory_order order) noexcept;

The template functions atomically store value as the stored value in *atom. They apply the memory constraints specified by order. The value of order should not be memory_order_consume, memory_order_acquire, or memory_order_acq_rel.

atomic_thread_fence

extern "C" void atomic_thread_fence(memory_order order) noexcept;

The function acts as a fence that establishes memory ordering requirements with respect to other fences. The order argument determines the type of the fence:

ATOMIC_VAR_INIT

#define ATOMIC_VAR_INIT(x) initializer

The macro expands to an expression that can be used to statically initialize a general-purpose atomic type to the value x, when x can be converted to atomic type's managed type.

ATOMIC_WCHAR_T_LOCK_FREE

#define ATOMIC_WCHAR_T_LOCK_FREE integer-value

The macro has a value that indicates whether the type atomic_wchar_t is lock free.

kill_dependency

template<class Ty>
    kill_dependency(Ty) noexcept;

The template function returns its argument. The evaluation of the argument does not carry a dependency to the function call. By breaking a possible dependency chain, the function might permit the compiler to generate more efficient code. See the discussion of the attribute [[carries_dependency]] in the C++ standard.

memory_order

typedef enum memory_order {
    memory_order_relaxed,
    memory_order_consume,
    memory_order_acquire,
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst
} memory_order;

The enumeration supplies symbolic names for synchronization operations on memory locations. These operations affect how assignments in one thread become visible in another, as set out in [intro.mulththread] in the C++ standard. The meanings of these names are:


See also the Table of Contents and the Index.

Copyright © 1992-2013 by P.J. Plauger. All rights reserved.