An atomic_­ref object applies atomic operations ([atomics.general]) to
the object referenced by *ptr such that,
for the lifetime ([basic.life]) of the atomic_­ref object,
the object referenced by *ptr is an atomic object ([intro.races]).

Atomic operations or the atomic_­ref constructor could acquire
a shared resource, such as a lock associated with the referenced object,
to enable atomic operations to be applied to the referenced object.

It then atomically compares the value representation of
the value referenced by *ptr for equality
with that previously retrieved from expected,
and if true, replaces the value referenced by *ptr
with that in desired.

If and only if the comparison is true,
memory is affected according to the value of success, and
if the comparison is false,
memory is affected according to the value of failure.

When only one memory_­order argument is supplied,
the value of success is order, and
the value of failure is order
except that a value of memory_­order_­acq_­rel shall be replaced by
the value memory_­order_­acquire and
a value of memory_­order_­release shall be replaced by
the value memory_­order_­relaxed.

If and only if the comparison is false then,
after the atomic operation,
the value in expected is replaced by
the value read from the value referenced by *ptr
during the atomic comparison.

If the operation returns true,
these operations are atomic read-modify-write operations ([intro.races])
on the value referenced by *ptr.

Otherwise, these operations are atomic load operations on that memory.

There are specializations of the atomic_­ref class template
for the integral types
char,
signedchar,
unsignedchar,
short,
unsignedshort,
int,
unsignedint,
long,
unsignedlong,
longlong,
unsignedlonglong,
char8_­t,
char16_­t,
char32_­t,
wchar_­t,
and any other types needed by the typedefs in the header <cstdint>.

For each such type integral,
the specialization atomic_­ref<integral> provides
additional atomic operations appropriate to integral types.

Remarks: For signed integer types,
the result is as if the object value and parameters
were converted to their corresponding unsigned types,
the computation performed on those types, and
the result converted back to the signed type.