Standard library header <atomic>

From cppreference.com
< cpplrm; | header

This header is part of the atomic operations library.

Classes

(C++11)
atomic class template and specializations for bool, integral, and pointer types
(class template)
provides atomic operations on non-atomic objects
(class template)
the lock-free boolean atomic type
(class)
defines memory ordering constraints for the given atomic operation
(enum)

Typedefs

std::atomic_bool std::atomic<bool>
std::atomic_char std::atomic<char>
std::atomic_schar std::atomic<signed char>
std::atomic_uchar std::atomic<unsigned char>
std::atomic_short std::atomic<short>
std::atomic_ushort std::atomic<unsigned short>
std::atomic_int std::atomic<int>
std::atomic_uint std::atomic<unsigned int>
std::atomic_long std::atomic<long>
std::atomic_ulong std::atomic<unsigned long>
std::atomic_llong std::atomic<long long>
std::atomic_ullong std::atomic<unsigned long long>
std::atomic_char16_t std::atomic<char16_t>
std::atomic_char32_t std::atomic<char32_t>
std::atomic_wchar_t std::atomic<wchar_t>
std::atomic_int8_t std::atomic<std::int8_t>
std::atomic_uint8_t std::atomic<std::uint8_t>
std::atomic_int16_t std::atomic<std::int16_t>
std::atomic_uint16_t std::atomic<std::uint16_t>
std::atomic_int32_t std::atomic<std::int32_t>
std::atomic_uint32_t std::atomic<std::uint32_t>
std::atomic_int64_t std::atomic<std::int64_t>
std::atomic_uint64_t std::atomic<std::uint64_t>
std::atomic_int_least8_t std::atomic<int_least8_t>
std::atomic_uint_least8_t std::atomic<uint_least8_t>
std::atomic_int_least16_t std::atomic<int_least16_t>
std::atomic_uint_least16_t std::atomic<uint_least16_t>
std::atomic_int_least32_t std::atomic<int_least32_t>
std::atomic_uint_least32_t std::atomic<uint_least32_t>
std::atomic_int_least64_t std::atomic<int_least64_t>
std::atomic_uint_least64_t std::atomic<uint_least64_t>
std::atomic_int_fast8_t std::atomic<int_fast8_t>
std::atomic_uint_fast8_t std::atomic<uint_fast8_t>
std::atomic_int_fast16_t std::atomic<int_fast16_t>
std::atomic_uint_fast16_t std::atomic<uint_fast16_t>
std::atomic_int_fast32_t std::atomic<int_fast32_t>
std::atomic_uint_fast32_t std::atomic<uint_fast32_t>
std::atomic_int_fast64_t std::atomic<int_fast64_t>
std::atomic_uint_fast64_t std::atomic<uint_fast64_t>
std::atomic_intptr_t std::atomic<intptr_t>
std::atomic_uintptr_t std::atomic<uintptr_t>
std::atomic_size_t std::atomic<size_t>
std::atomic_ptrdiff_t std::atomic<ptrdiff_t>
std::atomic_intmax_t std::atomic<intmax_t>
std::atomic_uintmax_t std::atomic<uintmax_t>

Functions

checks if the atomic type's operations are lock-free
(function template)
atomically replaces the value of the atomic object with a non-atomic argument
(function template)
atomically obtains the value stored in an atomic object
(function template)
atomically replaces the value of the atomic object with non-atomic argument and returns the old value of the atomic
(function template)
atomically compares the value of the atomic object with non-atomic argument and performs atomic exchange if equal or atomic load if not
(function template)
adds a non-atomic value to an atomic object and obtains the previous value of the atomic
(function template)
subtracts a non-atomic value from an atomic object and obtains the previous value of the atomic
(function template)
replaces the atomic object with the result of bitwise AND with a non-atomic argument and obtains the previous value of the atomic
(function template)
replaces the atomic object with the result of bitwise OR with a non-atomic argument and obtains the previous value of the atomic
(function template)
replaces the atomic object with the result of bitwise XOR with a non-atomic argument and obtains the previous value of the atomic
(function template)
atomically sets the flag to true and returns its previous value
(function)
atomically sets the value of the flag to false
(function)
non-atomic initialization of a default-constructed atomic object
(function template)
removes the specified object from the std::memory_order_consume dependency tree
(function template)
generic memory order-dependent fence synchronization primitive
(function)
fence between a thread and a signal handler executed in the same thread
(function)

Preprocessor macros

constant initialization of an atomic variable of static storage duration
(function macro)
initializes an std::atomic_flag to false
(macro constant)

Synopsis

namespace std {

    /* before C++17:

    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;

    */

    enum class memory_order : /*unspecified*/ {
        relaxed, consume, acquire, release, acq_rel, seq_cst
    };

    inline constexpr memory_order memory_order_relaxed = memory_order::relaxed;
    inline constexpr memory_order memory_order_consume = memory_order::consume;
    inline constexpr memory_order memory_order_acquire = memory_order::acquire;
    inline constexpr memory_order memory_order_release = memory_order::release;
    inline constexpr memory_order memory_order_acq_rel = memory_order::acq_rel;
    inline constexpr memory_order memory_order_seq_cst = memory_order::seq_cst;

    template <class T>
    T kill_dependency(T y) noexcept;

    // lock-free property
    #define ATOMIC_BOOL_LOCK_FREE /*unspecified*/
    #define ATOMIC_CHAR_LOCK_FREE /*unspecified*/
    #define ATOMIC_CHAR16_T_LOCK_FREE /*unspecified*/
    #define ATOMIC_CHAR32_T_LOCK_FREE /*unspecified*/
    #define ATOMIC_WCHAR_T_LOCK_FREE /*unspecified*/
    #define ATOMIC_SHORT_LOCK_FREE /*unspecified*/
    #define ATOMIC_INT_LOCK_FREE /*unspecified*/
    #define ATOMIC_LONG_LOCK_FREE /*unspecified*/
    #define ATOMIC_LLONG_LOCK_FREE /*unspecified*/
    #define ATOMIC_POINTER_LOCK_FREE /*unspecified*/

    // class template atomic_ref
    template<class T> struct atomic_ref;
    // partial specialization for pointers
    template<class T> struct atomic_ref<T*>;

    // generic atomic type
    template<class T> struct atomic;
    // specialization for pointers
    template<class T> struct atomic<T*>;

    // named typedefs
    using atomic_bool           = atomic<bool>;
    using atomic_char           = atomic<char>;
    using atomic_schar          = atomic<signed char>;
    using atomic_uchar          = atomic<unsigned char>;
    using atomic_short          = atomic<short>;
    using atomic_ushort         = atomic<unsigned short>;
    using atomic_int            = atomic<int>;
    using atomic_uint           = atomic<unsigned int>;
    using atomic_long           = atomic<long>;
    using atomic_ulong          = atomic<unsigned long>;
    using atomic_llong          = atomic<long long>;
    using atomic_ullong         = atomic<unsigned long long>;
    using atomic_char16_t       = atomic<char16_t>;
    using atomic_char32_t       = atomic<char32_t>;
    using atomic_wchar_t        = atomic<wchar_t>;

    using atomic_int8_t         = atomic<int8_t>;
    using atomic_uint8_t        = atomic<uint8_t>;
    using atomic_int16_t        = atomic<int16_t>;
    using atomic_uint16_t       = atomic<uint16_t>;
    using atomic_int32_t        = atomic<int32_t>;
    using atomic_uint32_t       = atomic<uint32_t>;
    using atomic_int64_t        = atomic<int64_t>;
    using atomic_uint64_t       = atomic<uint64_t>;

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

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

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

    // non-member functions
    template<class T>
    bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
    template<class T>
    bool atomic_is_lock_free(const atomic<T>*) noexcept;
    template<class T>
    void atomic_init(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    void atomic_init(atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    void atomic_store(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    void atomic_store(atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    void atomic_store_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
    template<class T>
    void atomic_store_explicit(atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
    template<class T>
    T atomic_load(const volatile atomic<T>*) noexcept;
    template<class T>
    T atomic_load(const atomic<T>*) noexcept;
    template<class T>
    T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
    template<class T>
    T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
    template<class T>
    T atomic_exchange(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    T atomic_exchange(atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    T atomic_exchange_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
    template<class T>
    T atomic_exchange_explicit(atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
    template<class T>
    bool atomic_compare_exchange_weak(volatile atomic<T>*,
                                      typename atomic<T>::value_type*,
                                      typename atomic<T>::value_type) noexcept;
    template<class T>
    bool atomic_compare_exchange_weak(atomic<T>*,
                                      typename atomic<T>::value_type*,
                                      typename atomic<T>::value_type) noexcept;
    template<class T>
    bool atomic_compare_exchange_strong(volatile atomic<T>*,
                                        typename atomic<T>::value_type*,
                                        typename atomic<T>::value_type) noexcept;
    template<class T>
    bool atomic_compare_exchange_strong(atomic<T>*,
                                        typename atomic<T>::value_type*,
                                        typename atomic<T>::value_type) noexcept;
    template<class T>
    bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*,
                                               typename atomic<T>::value_type*,
                                               typename atomic<T>::value_type,
                                               memory_order, memory_order) noexcept;
    template<class T>
    bool atomic_compare_exchange_weak_explicit(atomic<T>*,
                                               typename atomic<T>::value_type*,
                                               typename atomic<T>::value_type,
                                               memory_order, memory_order) noexcept;
    template<class T>
    bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*,
                                                 typename atomic<T>::value_type*,
                                                 typename atomic<T>::value_type,
                                                 memory_order, memory_order) noexcept;
    template<class T>
    bool atomic_compare_exchange_strong_explicit(atomic<T>*,
                                                 typename atomic<T>::value_type*,
                                                 typename atomic<T>::value_type,
                                                 memory_order, memory_order) noexcept;

    template<class T>
    T atomic_fetch_add(volatile atomic<T>*, typename atomic<T>::difference_type) noexcept;
    template<class T>
    T atomic_fetch_add(atomic<T>*, typename atomic<T>::difference_type) noexcept;
    template<class T>
    T atomic_fetch_add_explicit(volatile atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
    template<class T>
    T atomic_fetch_add_explicit(atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
    template<class T>
    T atomic_fetch_sub(volatile atomic<T>*, typename atomic<T>::difference_type) noexcept;
    template<class T>
    T atomic_fetch_sub(atomic<T>*, typename atomic<T>::difference_type) noexcept;
    template<class T>
    T atomic_fetch_sub_explicit(volatile atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
    template<class T>
    T atomic_fetch_sub_explicit(atomic<T>*, typename atomic<T>::difference_type,
                                memory_order) noexcept;
    template<class T>
    T atomic_fetch_and(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    T atomic_fetch_and(atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    T atomic_fetch_and_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
    template<class T>
    T atomic_fetch_and_explicit(atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
    template<class T>
    T atomic_fetch_or(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    T atomic_fetch_or(atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    T atomic_fetch_or_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
    template<class T>
    T atomic_fetch_or_explicit(atomic<T>*, typename atomic<T>::value_type,
                               memory_order) noexcept;
    template<class T>
    T atomic_fetch_xor(volatile atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    T atomic_fetch_xor(atomic<T>*, typename atomic<T>::value_type) noexcept;
    template<class T>
    T atomic_fetch_xor_explicit(volatile atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;
    template<class T>
    T atomic_fetch_xor_explicit(atomic<T>*, typename atomic<T>::value_type,
                                memory_order) noexcept;

    // initialization
    #define ATOMIC_VAR_INIT(value) /*see description*/

    // flag type and operations
    struct 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;
    void atomic_flag_clear(volatile atomic_flag*) noexcept;
    void atomic_flag_clear(atomic_flag*) noexcept;
    void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order) noexcept;
    void atomic_flag_clear_explicit(atomic_flag*, memory_order) noexcept;

    #define ATOMIC_FLAG_INIT /*see description*/

    // fences
    extern "C" void atomic_thread_fence(memory_order) noexcept;
    extern "C" void atomic_signal_fence(memory_order) noexcept;

Class std::atomic

template <class T> struct atomic {
    using value_type = T;

    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;
    void store(T, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(T, memory_order = memory_order_seq_cst) noexcept;
    T load(memory_order = memory_order_seq_cst) const volatile noexcept;
    T load(memory_order = memory_order_seq_cst) const noexcept;
    operator T() const volatile noexcept;
    operator T() const noexcept;
    T exchange(T, memory_order = memory_order_seq_cst) volatile noexcept;
    T exchange(T, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(T&, T,
                               memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(T&, T,
                               memory_order, memory_order) noexcept;
    bool compare_exchange_strong(T&, T,
                                 memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(T&, T,
                                 memory_order, memory_order) noexcept;
    bool compare_exchange_weak(T&, T,
                               memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(T&, T,
                               memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(T&, T,
                                 memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(T&, T,
                                 memory_order = memory_order_seq_cst) noexcept;

    atomic() noexcept = default;
    constexpr atomic(T) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    T operator=(T) volatile noexcept;
    T operator=(T) noexcept;
};

Specializations of std::atomic for integral types

template<> struct atomic</*integral*/> {
    using value_type = /*integral*/;
    using difference_type = value_type;

    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;
    operator /*integral*/() const volatile noexcept;
    operator /*integral*/() 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) volatile noexcept;
    bool compare_exchange_weak(/*integral*/&, /*integral*/,
                               memory_order, memory_order) noexcept;
    bool compare_exchange_strong(/*integral*/&, /*integral*/,
                                 memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(/*integral*/&, /*integral*/,
                                 memory_order, memory_order) 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_strong(/*integral*/&, /*integral*/,
                                 memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(/*integral*/&, /*integral*/,
                                 memory_order = memory_order_seq_cst) 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;

    atomic() noexcept = default;
    constexpr atomic(/*integral*/) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    /*integral*/ operator=(/*integral*/) volatile noexcept;
    /*integral*/ operator=(/*integral*/) noexcept;
    /*integral*/ operator++(int) volatile noexcept;
    /*integral*/ operator++(int) noexcept;
    /*integral*/ operator--(int) volatile noexcept;
    /*integral*/ operator--(int) noexcept;
    /*integral*/ operator++() volatile noexcept;
    /*integral*/ operator++() 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;
    /*integral*/ operator^=(/*integral*/) volatile noexcept;
    /*integral*/ operator^=(/*integral*/) noexcept;
};

Specializations of std::atomic for floating point types

template<> struct atomic</*floating-point*/> {
    using value_type = /*floating-point*/;
    using difference_type = value_type;
    static constexpr bool is_always_lock_free = /*implementation-defined*/;
    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;
    void store(/*floating-point*/, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(/*floating-point*/, memory_order = memory_order_seq_cst) noexcept;
    /*floating-point*/ load(memory_order = memory_order_seq_cst) volatile noexcept;
    /*floating-point*/ load(memory_order = memory_order_seq_cst) noexcept;
    operator /*floating-point*/() volatile noexcept;
    operator /*floating-point*/() noexcept;
    /*floating-point*/ exchange(/*floating-point*/,
                                memory_order = memory_order_seq_cst) volatile noexcept;
    /*floating-point*/ exchange(/*floating-point*/,
                                memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(/*floating-point*/&, /*floating-point*/,
                                memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(/*floating-point*/&, /*floating-point*/,
                               memory_order, memory_order) noexcept;
    bool compare_exchange_strong(/*floating-point*/&, /*floating-point*/,
                                 memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(/*floating-point*/&, /*floating-point*/,
                                 memory_order, memory_order) noexcept;
    bool compare_exchange_weak(/*floating-point*/&, /*floating-point*/,
                               memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(/*floating-point*/&, /*floating-point*/,
                               memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(/*floating-point*/&, /*floating-point*/,
                                 memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(/*floating-point*/&, /*floating-point*/,
                                 memory_order = memory_order_seq_cst) noexcept;

    /*floating-point*/ fetch_add(/*floating-point*/,
                                 memory_order = memory_order_seq_cst) volatile noexcept;
    /*floating-point*/ fetch_add(/*floating-point*/,
                                 memory_order = memory_order_seq_cst) noexcept;
    /*floating-point*/ fetch_sub(/*floating-point*/,
                                 memory_order = memory_order_seq_cst) volatile noexcept;
    /*floating-point*/ fetch_sub(/*floating-point*/,
                                 memory_order = memory_order_seq_cst) noexcept;

    atomic() noexcept = default;
    constexpr atomic(/*floating-point*/) noexcept;

    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    /*floating-point*/ operator=(/*floating-point*/) volatile noexcept;
    /*floating-point*/ operator=(/*floating-point*/) noexcept;

    /*floating-point*/ operator+=(/*floating-point*/) volatile noexcept;
    /*floating-point*/ operator+=(/*floating-point*/) noexcept;
    /*floating-point*/ operator-=(/*floating-point*/) volatile noexcept;
    /*floating-point*/ operator-=(/*floating-point*/) noexcept;
};

Specializations of std::atomic for pointer types

template <class T> struct atomic<T*> {
    using value_type = T*;
    using difference_type = ptrdiff_t;

    bool is_lock_free() const volatile noexcept;
    bool is_lock_free() const noexcept;
    void store(T*, memory_order = memory_order_seq_cst) volatile noexcept;
    void store(T*, memory_order = memory_order_seq_cst) noexcept;
    T* load(memory_order = memory_order_seq_cst) const volatile noexcept;
    T* load(memory_order = memory_order_seq_cst) const noexcept;
    operator T*() const volatile noexcept;
    operator T*() const noexcept;
    T* exchange(T*, memory_order = memory_order_seq_cst) volatile noexcept;
    T* exchange(T*, memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order, memory_order) volatile noexcept;
    bool compare_exchange_weak(T*&, T*, memory_order, memory_order) noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order, memory_order) volatile noexcept;
    bool compare_exchange_strong(T*&, T*, memory_order, memory_order) noexcept;
    bool compare_exchange_weak(T*&, T*,
                               memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_weak(T*&, T*,
                               memory_order = memory_order_seq_cst) noexcept;
    bool compare_exchange_strong(T*&, T*,
                                 memory_order = memory_order_seq_cst) volatile noexcept;
    bool compare_exchange_strong(T*&, T*,
                                 memory_order = memory_order_seq_cst) noexcept;
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept;
    T* fetch_add(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) volatile noexcept;
    T* fetch_sub(ptrdiff_t, memory_order = memory_order_seq_cst) noexcept;

    atomic() noexcept = default;
    constexpr atomic(T*) noexcept;
    atomic(const atomic&) = delete;
    atomic& operator=(const atomic&) = delete;
    atomic& operator=(const atomic&) volatile = delete;
    T* operator=(T*) volatile noexcept;
    T* operator=(T*) noexcept;
    T* operator++(int) volatile noexcept;
    T* operator++(int) noexcept;
    T* operator--(int) volatile noexcept;
    T* operator--(int) noexcept;
    T* operator++() volatile noexcept;
    T* operator++() noexcept;
    T* operator--() volatile noexcept;
    T* operator--() noexcept;
    T* operator+=(ptrdiff_t) volatile noexcept;
    T* operator+=(ptrdiff_t) noexcept;
    T* operator-=(ptrdiff_t) volatile noexcept;
    T* operator-=(ptrdiff_t) noexcept;
};

Class std::atomic_ref

template<class T> struct atomic_ref {
private:
    T* ptr; // exposition only
public:
    using value_type = T;
    static constexpr bool is_always_lock_free = /*implementation-defined*/;
    static constexpr size_t required_alignment = /*implementation-defined*/;

    atomic_ref() = delete;
    atomic_ref& operator=(const atomic_ref&) = delete;

    explicit atomic_ref(T&);
    atomic_ref(const atomic_ref&) noexcept;

    T operator=(T) const noexcept;
    operator T() const noexcept;

    bool is_lock_free() const noexcept;
    void store(T, memory_order = memory_order_seq_cst) const noexcept;
    T load(memory_order = memory_order_seq_cst) const noexcept;
    T exchange(T, memory_order = memory_order_seq_cst) const noexcept;
    bool compare_exchange_weak(T&, T,
                               memory_order, memory_order) const noexcept;
    bool compare_exchange_strong(T&, T,
                                 memory_order, memory_order) const noexcept;
    bool compare_exchange_weak(T&, T,
                               memory_order = memory_order_seq_cst) const noexcept;
    bool compare_exchange_strong(T&, T,
                                 memory_order = memory_order_seq_cst) const noexcept;
};

Specializations of std::atomic_ref for integral types

template<> struct atomic_ref</*integral*/> {
private:
    /*integral*/* ptr; // exposition only
public:
    using value_type = /*integral*/;
    using difference_type = value_type;
    static constexpr bool is_always_lock_free = /*implementation-defined*/;
    static constexpr size_t required_alignment = /*implementation-defined*/;

    atomic_ref() = delete;
    atomic_ref& operator=(const atomic_ref&) = delete;

    explicit atomic_ref(/*integral*/&);
    atomic_ref(const atomic_ref&) noexcept;

    /*integral*/ operator=(/*integral*/) const noexcept;
    operator /*integral*/() const noexcept;

    bool is_lock_free() const noexcept;
    void store(/*integral*/, memory_order = memory_order_seq_cst) const noexcept;
    /*integral*/ load(memory_order = memory_order_seq_cst) const noexcept;
    /*integral*/ exchange(/*integral*/,
                           memory_order = memory_order_seq_cst) const noexcept;
    bool compare_exchange_weak(/*integral*/&, /*integral*/,
                               memory_order, memory_order) const noexcept;
    bool compare_exchange_strong(/*integral*/&, /*integral*/,
                                 memory_order, memory_order) const noexcept;
    bool compare_exchange_weak(/*integral*/&, /*integral*/,
                               memory_order = memory_order_seq_cst) const noexcept;
    bool compare_exchange_strong(/*integral*/&, /*integral*/,
                                 memory_order = memory_order_seq_cst) const noexcept;

    /*integral*/ fetch_add(/*integral*/,
                           memory_order = memory_order_seq_cst) const noexcept;
    /*integral*/ fetch_sub(/*integral*/,
                           memory_order = memory_order_seq_cst) const noexcept;
    /*integral*/ fetch_and(/*integral*/,
                           memory_order = memory_order_seq_cst) const noexcept;
    /*integral*/ fetch_or(/*integral*/,
                          memory_order = memory_order_seq_cst) const noexcept;
    /*integral*/ fetch_xor(/*integral*/,
                           memory_order = memory_order_seq_cst) const noexcept;

    /*integral*/ operator++(int) const noexcept;
    /*integral*/ operator--(int) const noexcept;
    /*integral*/ operator++() const noexcept;
    /*integral*/ operator--() const noexcept;
    /*integral*/ operator+=(/*integral*/) const noexcept;
    /*integral*/ operator-=(/*integral*/) const noexcept;
    /*integral*/ operator&=(/*integral*/) const noexcept;
    /*integral*/ operator

Specializations of std::atomic_ref for floating-point types

template<> struct atomic_ref</*floating-point*/> {
private:
    /*floating-point*/* ptr; // exposition only
public:
    using value_type = /*floating-point*/;
    using difference_type = value_type;
    static constexpr bool is_always_lock_free = /*implementation-defined*/;
    static constexpr size_t required_alignment = /*implementation-defined*/;

    atomic_ref() = delete;
    atomic_ref& operator=(const atomic_ref&) = delete;

    explicit atomic_ref(/*floating-point*/&);
    atomic_ref(const atomic_ref&) noexcept;

    /*floating-point*/ operator=(/*floating-point*/) noexcept;
    operator /*floating-point*/() const noexcept;

    bool is_lock_free() const noexcept;
    void store(/*floating-point*/, memory_order = memory_order_seq_cst) const noexcept;
    /*floating-point*/ load(memory_order = memory_order_seq_cst) const noexcept;
    /*floating-point*/ exchange(/*floating-point*/,
                                memory_order = memory_order_seq_cst) const noexcept;
    bool compare_exchange_weak(/*floating-point*/&, /*floating-point*/,
                               memory_order, memory_order) const noexcept;
    bool compare_exchange_strong(/*floating-point*/&, /*floating-point*/,
                                 memory_order, memory_order) const noexcept;
    bool compare_exchange_weak(/*floating-point*/&, /*floating-point*/,
                               memory_order = memory_order_seq_cst) const noexcept;
    bool compare_exchange_strong(/*floating-point*/&, /*floating-point*/,
                                 memory_order = memory_order_seq_cst) const noexcept;

    /*floating-point*/ fetch_add(/*floating-point*/,
                                 memory_order = memory_order_seq_cst) const noexcept;
    /*floating-point*/ fetch_sub(/*floating-point*/,
                                 memory_order = memory_order_seq_cst) const noexcept;

    /*floating-point*/ operator+=(/*floating-point*/) const noexcept;
    /*floating-point*/ operator-=(/*floating-point*/) const noexcept;
};

Specializations of std::atomic_ref for pointer types

template<class T> struct atomic_ref<T*> {
private:
    T** ptr; // exposition only
public:
    using value_type = T*;
    using difference_type = ptrdiff_t;
    static constexpr bool is_always_lock_free = /*implementation-defined*/;
    static constexpr size_t required_alignment = /*implementation-defined*/;

    atomic_ref() = delete;
    atomic_ref& operator=(const atomic_ref&) = delete;

    explicit atomic_ref(T*&);
    atomic_ref(const atomic_ref&) noexcept;

    T* operator=(T*) const noexcept;
    operator T*() const noexcept;

    bool is_lock_free() const noexcept;
    void store(T*, memory_order = memory_order_seq_cst) const noexcept;
    T* load(memory_order = memory_order_seq_cst) const noexcept;
    T* exchange(T*, memory_order = memory_order_seq_cst) const noexcept;
    bool compare_exchange_weak(T*&, T*,
                               memory_order, memory_order) const noexcept;
    bool compare_exchange_strong(T*&, T*,
                                 memory_order, memory_order) const noexcept;
    bool compare_exchange_weak(T*&, T*,
                               memory_order = memory_order_seq_cst) const noexcept;
    bool compare_exchange_strong(T*&, T*,
                                 memory_order = memory_order_seq_cst) const noexcept;

    T* fetch_add(difference_type, memory_order = memory_order_seq_cst) const noexcept;
    T* fetch_sub(difference_type, memory_order = memory_order_seq_cst) const noexcept;

    T* operator++(int) const noexcept;
    T* operator--(int) const noexcept;
    T* operator++() const noexcept;
    T* operator--() const noexcept;
    T* operator+=(difference_type) const noexcept;
    T* operator-=(difference_type) const noexcept;
};

Class std::atomic_flag

typedef struct atomic_flag {
    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() noexcept = default;
    atomic_flag(const atomic_flag&) = delete;
    atomic_flag& operator=(const atomic_flag&) = delete;
    atomic_flag& operator=(const atomic_flag&) volatile = delete;
} atomic_flag;