32 Concurrency support library [thread]

32.5 Atomic operations [atomics]

32.5.7 Class template atomic_ref [atomics.ref.generic]

32.5.7.4 Specializations for floating-point types [atomics.ref.float]

There are specializations of the atomic_ref class template for all floating-point types.
For each such type floating-point-type, the specialization atomic_ref<floating-point-type> provides additional atomic operations appropriate to floating-point types.
The program is ill-formed if is_always_lock_free is false and is_volatile_v<T> is true.
namespace std { template<> struct atomic_ref<floating-point-type> { private: floating-point-type* ptr; // exposition only public: using value_type = remove_cv_t<floating-point-type>; using difference_type = value_type; static constexpr size_t required_alignment = implementation-defined; static constexpr bool is_always_lock_free = implementation-defined; bool is_lock_free() const noexcept; constexpr explicit atomic_ref(floating-point-type&); constexpr atomic_ref(const atomic_ref&) noexcept; atomic_ref& operator=(const atomic_ref&) = delete; constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type operator=(value_type) const noexcept; constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept; constexpr operator value_type() const noexcept; constexpr value_type exchange(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr bool compare_exchange_weak(value_type&, value_type, memory_order, memory_order) const noexcept; constexpr bool compare_exchange_strong(value_type&, value_type, memory_order, memory_order) const noexcept; constexpr bool compare_exchange_weak(value_type&, value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr bool compare_exchange_strong(value_type&, value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_add(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_sub(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_max(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_min(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_fmaximum(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_fminimum(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_fmaximum_num(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_fminimum_num(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void store_add(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void store_sub(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void store_max(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void store_min(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void store_fmaximum(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void store_fminimum(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void store_fmaximum_num(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void store_fminimum_num(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type operator+=(value_type) const noexcept; constexpr value_type operator-=(value_type) const noexcept; constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void notify_one() const noexcept; constexpr void notify_all() const noexcept; constexpr floating-point-type* address() const noexcept; }; }
Descriptions are provided below only for members that differ from the primary template.
The following operations perform arithmetic 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.
constexpr value_type fetch_key(value_type operand, memory_order order = memory_order::seq_cst) const noexcept;
Constraints: is_const_v<floating-point-type> is false.
Effects: Atomically replaces the value referenced by *ptr with the result of the computation applied to the value referenced by *ptr and the given operand.
Memory is affected according to the value of order.
These operations are atomic read-modify-write operations ([intro.races]).
Returns: Atomically, the value referenced by *ptr 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<value_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 *ptr 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 *ptr 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 *ptr and the first parameter as the arguments, except that:
    • If both arguments are NaN, an unspecified NaN value is stored at *ptr.
    • If exactly one argument is a NaN, either the other argument or an unspecified NaN value is stored at *ptr; it is unspecified which.
    • If the arguments are differently signed zeros, which of these values is stored at *ptr is unspecified.
Recommended practice: The implementation of fetch_max and fetch_min should treat negative zero as smaller than positive zero.
constexpr void store_key(value_type operand, memory_order order = memory_order::seq_cst) const noexcept;
Preconditions: order is memory_order​::​relaxed, memory_order​::​release, or memory_order​::​seq_cst.
Effects: Atomically replaces the value referenced by *ptr with the result of the computation applied to the value referenced by *ptr 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 *ptr 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 *ptr 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 *ptr and the first parameter as the arguments, except that:
    • If both arguments are NaN, an unspecified NaN value is stored at *ptr.
    • If exactly one argument is a NaN, either the other argument or an unspecified NaN value is stored at *ptr, it is unspecified which.
    • If the arguments are differently signed zeros, which of these values is stored at *ptr is unspecified.
Recommended practice: The implementation of store_max and store_min should treat negative zero as smaller than positive zero.
constexpr value_type operator op=(value_type operand) const noexcept;
Constraints: is_const_v<floating-point-type> is false.
Effects: Equivalent to: return fetch_key(operand) op operand;