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() = 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; }; }

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

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

```
floating-point operator op=(floating-point operand) const noexcept;
```

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