32 Concurrency support library [thread]

32.5 Atomic operations [atomics]

32.5.8 Class template atomic [atomics.types.generic]

32.5.8.4 Specializations for floating-point types [atomics.types.float]

There are specializations of the atomic class template for all cv-unqualified floating-point types.
For each such type floating-point-type, the specialization atomic<floating-point-type> provides additional atomic operations appropriate to floating-point types.
namespace std { template<> struct atomic<floating-point-type> { using value_type = floating-point-type; 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; constexpr atomic() noexcept; constexpr atomic(floating-point-type) noexcept; atomic(const atomic&) = delete; atomic& operator=(const atomic&) = delete; atomic& operator=(const atomic&) volatile = delete; void store(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store(floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type operator=(floating-point-type) volatile noexcept; constexpr floating-point-type operator=(floating-point-type) noexcept; floating-point-type load(memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-point-type load(memory_order = memory_order::seq_cst) noexcept; operator floating-point-type() volatile noexcept; constexpr operator floating-point-type() noexcept; floating-point-type exchange(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-point-type exchange(floating-point-type, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(floating-point-type&, floating-point-type, memory_order, memory_order) volatile noexcept; constexpr bool compare_exchange_weak(floating-point-type&, floating-point-type, memory_order, memory_order) noexcept; bool compare_exchange_strong(floating-point-type&, floating-point-type, memory_order, memory_order) volatile noexcept; constexpr bool compare_exchange_strong(floating-point-type&, floating-point-type, memory_order, memory_order) noexcept; bool compare_exchange_weak(floating-point-type&, floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_weak(floating-point-type&, floating-point-type, memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(floating-point-type&, floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_strong(floating-point-type&, floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type fetch_add(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-point-type fetch_add(floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type fetch_sub(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-point-type fetch_sub(floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type fetch_max(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-point-type fetch_max(floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type fetch_min(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-poin-typet fetch_min(floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type fetch_fmaximum(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-point-type fetch_fmaximum(floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type fetch_fminimum(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-point-type fetch_fminimum(floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type fetch_fmaximum_num(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-point-type fetch_fmaximum_num(floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type fetch_fminimum_num(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr floating-point-type fetch_fminimum_num(floating-point-type, memory_order = memory_order::seq_cst) noexcept; void store_add(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_add(floating-point-type, memory_order = memory_order::seq_cst) noexcept; void store_sub(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_sub(floating-point-type, memory_order = memory_order::seq_cst) noexcept; void store_max(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_max(floating-point-type, memory_order = memory_order::seq_cst) noexcept; void store_min(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_min(floating-point-type, memory_order = memory_order::seq_cst) noexcept; void store_fmaximum(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_fmaximum(floating-point-type, memory_order = memory_order::seq_cst) noexcept; void store_fminimum(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_fminimum(floating-point-type, memory_order = memory_order::seq_cst) noexcept; void store_fmaximum_num(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_fmaximum_num(floating-point-type, memory_order = memory_order::seq_cst) noexcept; void store_fminimum_num(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_fminimum_num(floating-point-type, memory_order = memory_order::seq_cst) noexcept; floating-point-type operator+=(floating-point-type) volatile noexcept; constexpr floating-point-type operator+=(floating-point-type) noexcept; floating-point-type operator-=(floating-point-type) volatile noexcept; constexpr floating-point-type operator-=(floating-point-type) noexcept; void wait(floating-point-type, memory_order = memory_order::seq_cst) const volatile noexcept; constexpr void wait(floating-point-type, memory_order = memory_order::seq_cst) const noexcept; void notify_one() volatile noexcept; constexpr void notify_one() noexcept; void notify_all() volatile noexcept; constexpr void notify_all() noexcept; }; }
The atomic floating-point specializations are standard-layout structs.
They each have a trivial destructor.
Descriptions are provided below only for members that differ from the primary template.
The following operations perform arithmetic addition and subtraction computations.
The correspondence among key, operator, and computation is specified in Table 155, except for the keys max, min, fmaximum, fminimum, fmaximum_num, and fminimum_num, which are specified below.
T fetch_key(T operand, memory_order order = memory_order::seq_cst) volatile noexcept; constexpr T fetch_key(T operand, memory_order order = memory_order::seq_cst) noexcept;
Constraints: For the volatile overload of this function, is_always_lock_free is true.
Effects: Atomically replaces the value pointed to by this with the result of the computation applied to the value pointed to by this and the given operand.
Memory is affected according to the value of order.
These operations are atomic read-modify-write operations ([intro.multithread]).
Returns: Atomically, the value pointed to by this immediately before the effects.
Remarks: If the result is not a representable value for its type ([expr.pre]) the result is unspecified, but the operations otherwise have no undefined behavior.
Atomic arithmetic operations on floating-point-type should conform to the std​::​numeric_limits<floating-point-type> traits associated with the floating-point type ([limits.syn]).
The floating-point environment ([cfenv]) for atomic arithmetic operations on floating-point-type may be different than the calling thread's floating-point environment.
  • For fetch_fmaximum and fetch_fminimum, the maximum and minimum computation is performed as if by fmaximum and fminimum, respectively, with the value pointed to by this and the first parameter as the arguments.
  • For fetch_fmaximum_num and fetch_fminimum_num, the maximum and minimum computation is performed as if by fmaximum_num and fminimum_num, respectively, with the value pointed to by this and the first parameter as the arguments.
  • For fetch_max and fetch_min, the maximum and minimum computation is performed as if by fmaximum_num and fminimum_num, respectively, with the value pointed to by this and the first parameter as the arguments, except that:
    • If both arguments are NaN, an unspecified NaN value replaces the value pointed to by this.
    • If exactly one argument is a NaN, either the other argument or an unspecified NaN value replaces the value pointed to by this; it is unspecified which.
    • If the arguments are differently signed zeros, which of these values replaces the value pointed to by this is unspecified.
Recommended practice: The implementation of fetch_max and fetch_min should treat negative zero as smaller than positive zero.
void store_key(floating-point-type operand, memory_order order = memory_order::seq_cst) volatile noexcept; constexpr void store_key(floating-point-type operand, memory_order order = memory_order::seq_cst) noexcept;
Constraints: For the volatile overload of this function, is_always_lock_free is true.
Preconditions: order is memory_order​::​relaxed, memory_order​::​release, or memory_order​::​seq_cst.
Effects: Atomically replaces the value pointed to by this with the result of the computation applied to the value pointed to by this and the given operand.
Memory is affected according to the value of order.
These operations are atomic modify-write operations ([atomics.order]).
Remarks: If the result is not a representable value for its type ([expr.pre]) the result is unspecified, but the operations otherwise have no undefined behavior.
Atomic arithmetic operations on floating-point-type should conform to the numeric_limits<floating-point-type> traits associated with the floating-point type ([limits.syn]).
The floating-point environment ([cfenv]) for atomic arithmetic operations on floating-point-type may be different than the calling thread's floating-point environment.
The arithmetic rules of floating-point atomic modify-write operations may be different from operations on floating-point types or atomic floating-point types.
[Note 1: 
Tree reductions are permitted for atomic modify-write operations.
— end note]
  • For store_fmaximum and store_fminimum, the maximum and minimum computation is performed as if by fmaximum and fminimum, respectively, with the value pointed to by this and the first parameter as the arguments.
  • For store_fmaximum_num and store_fminimum_num, the maximum and minimum computation is performed as if by fmaximum_num and fminimum_num, respectively, with the value pointed to by this and the first parameter as the arguments.
  • For store_max and store_min, the maximum and minimum computation is performed as if by fmaximum_num and fminimum_num, respectively, with the value pointed to by this and the first parameter as the arguments, except that:
    • If both arguments are NaN, an unspecified NaN value replaces the value pointed to by this.
    • If exactly one argument is a NaN, either the other argument or an unspecified NaN value replaces the value pointed to by this; it is unspecified which.
    • If the arguments are differently signed zeros, which of these values replaces the value pointed to by this is unspecified.
Recommended practice: The implementation of store_max and store_min should treat negative zero as smaller than positive zero.
T operator op=(T operand) volatile noexcept; constexpr T operator op=(T operand) noexcept;
Constraints: For the volatile overload of this function, is_always_lock_free is true.
Effects: Equivalent to: return fetch_key(operand) op operand;
Remarks: If the result is not a representable value for its type ([expr.pre]) the result is unspecified, but the operations otherwise have no undefined behavior.
Atomic arithmetic operations on floating-point-type should conform to the std​::​numeric_limits<floating-point-type> traits associated with the floating-point type ([limits.syn]).
The floating-point environment ([cfenv]) for atomic arithmetic operations on floating-point-type may be different than the calling thread's floating-point environment.