There are specializations of the atomic_ref class template
for all cv-unqualified floating-point types.

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 size_t required_alignment = *implementation-defined*;
static constexpr bool is_always_lock_free = *implementation-defined*;
bool is_lock_free() const noexcept;
explicit atomic_ref(*floating-point*&);
atomic_ref(const atomic_ref&) noexcept;
atomic_ref& operator=(const atomic_ref&) = delete;
void store(*floating-point*, memory_order = memory_order::seq_cst) const noexcept;
*floating-point* operator=(*floating-point*) const noexcept;
*floating-point* load(memory_order = memory_order::seq_cst) const noexcept;
operator *floating-point*() 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;
void wait(*floating-point*, memory_order = memory_order::seq_cst) const noexcept;
void notify_one() const noexcept;
void notify_all() const noexcept;
};
}

*floating-point* fetch_*key*(*floating-point* operand,
memory_order order = memory_order::seq_cst) const noexcept;

Memory is affected according to the value of order.

These operations are atomic read-modify-write operations ([intro.races]).

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;