Files
2025-10-25 03:02:53 +03:00

12 KiB
Raw Permalink Blame History

[atomics.ref.float]

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]

1

#

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.

2

#

The program is ill-formed if is_always_lock_free is false andis_volatile_v<floating-point-type> is true.

namespace std {template<> struct atomic_ref<floating-point-type> {private:floating-point-type* ptr; // exposition onlypublic: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; };}

3

#

Descriptions are provided below only for members that differ from the primary template.

4

#

The following operations perform arithmetic computations.

The correspondence among key, operator, and computation is specified in Table 155, except for the keysmax,min,fmaximum,fminimum,fmaximum_num, andfminimum_num, which are specified below.

🔗

constexpr value_type fetch_key(value_type operand, memory_order order = memory_order::seq_cst) const noexcept;

5

#

Constraints: is_const_v<floating-point-type> is false.

6

#

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]).

7

#

Returns: Atomically, the value referenced by *ptr immediately before the effects.

8

#

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.

9

#

  • (9.1)

    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.

  • (9.2)

    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.

  • (9.3)

    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:

    • (9.3.1)

      If both arguments are NaN, an unspecified NaN value is stored at *ptr.

    • (9.3.2)

      If exactly one argument is a NaN, either the other argument or an unspecified NaN value is stored at *ptr; it is unspecified which.

    • (9.3.3)

      If the arguments are differently signed zeros, which of these values is stored at *ptr is unspecified.

10

#

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;

11

#

Preconditions: order is memory_order::relaxed,memory_order::release, ormemory_order::seq_cst.

12

#

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]).

13

#

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]

14

#

  • (14.1)

    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.

  • (14.2)

    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.

  • (14.3)

    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:

    • (14.3.1)

      If both arguments are NaN, an unspecified NaN value is stored at *ptr.

    • (14.3.2)

      If exactly one argument is a NaN, either the other argument or an unspecified NaN value is stored at *ptr, it is unspecified which.

    • (14.3.3)

      If the arguments are differently signed zeros, which of these values is stored at *ptr is unspecified.

15

#

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;

16

#

Constraints: is_const_v<floating-point-type> is false.

17

#

Effects: Equivalent to:return fetch_key(operand) op operand;