31 Atomic operations library [atomics]

31.6 Class template atomic_­ref [atomics.ref.generic]

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

There are specializations of the atomic_­ref class template for the floating-point types float, double, and long double.
For each such type floating-point, the specialization atomic_­ref<floating-point> provides additional atomic operations appropriate to floating-point types.
namespace std {
  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& 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;
  };
}
Descriptions are provided below only for members that differ from the primary template.
The following operations perform arithmetic computations.
The key, operator, and computation correspondence are identified in [tab:atomic.arithmetic.computations]Table *tab:atomic.arithmetic.computations.
floating-point fetch_key(floating-point operand, memory_order order = memory_order_seq_cst) const noexcept;
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 should conform to the std::numeric_­limits<floating-point> traits associated with the floating-point type ([limits.syn]).
The floating-point environment ([cfenv]) for atomic arithmetic operations on floating-point may be different than the calling thread's floating-point environment.
floating-point operator op=(floating-point operand) const noexcept;
Effects: Equivalent to: return fetch_­key(operand) op operand;