[atomics.ref.ops]

# 32 Concurrency support library [[thread]](./#thread)

## 32.5 Atomic operations [[atomics]](atomics#ref.ops)

### 32.5.7 Class template atomic_ref [[atomics.ref.generic]](atomics.ref.generic#atomics.ref.ops)

#### 32.5.7.2 Operations [atomics.ref.ops]

[ð](#lib:required_alignment,atomic_ref)

`static constexpr size_t required_alignment;
`

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3286)

The alignment required for an object to be referenced by an atomic reference,
which is at least alignof(T)[.](#1.sentence-1)

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3290)

[*Note [1](#note-1)*:

Hardware could require an object
referenced by an atomic_ref to have stricter alignment ([[basic.align]](basic.align "6.8.3 Alignment"))
than other objects of type T[.](#2.sentence-1)

Further, whether operations on an atomic_ref are lock-free could depend on the alignment of the referenced object[.](#2.sentence-2)

For example, lock-free operations on std​::​complex<double> could be supported only if aligned to 2*alignof(double)[.](#2.sentence-3)

â *end note*]

[ð](#lib:is_always_lock_free,atomic_ref)

`static constexpr bool is_always_lock_free;
`

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3312)

The static data member is_always_lock_free is true if the atomic_ref type's operations are always lock-free,
and false otherwise[.](#3.sentence-1)

[ð](#lib:is_lock_free,atomic_ref)

`bool is_lock_free() const noexcept;
`

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3327)

*Returns*: true if operations on all objects of the type atomic_ref<T> are lock-free,false otherwise[.](#4.sentence-1)

[ð](#lib:atomic_ref,constructor)

`constexpr atomic_ref(T& obj);
`

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3343)

*Preconditions*: The referenced object is aligned to required_alignment[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3347)

*Postconditions*: *this references obj[.](#6.sentence-1)

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3351)

*Throws*: Nothing[.](#7.sentence-1)

[ð](#lib:atomic_ref,constructor_)

`constexpr atomic_ref(const atomic_ref& ref) noexcept;
`

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3365)

*Postconditions*: *this references the object referenced by ref[.](#8.sentence-1)

[ð](#lib:store,atomic_ref)

`constexpr void store(value_type desired,
                     memory_order order = memory_order::seq_cst) const noexcept;
`

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3380)

*Constraints*: is_const_v<T> is false[.](#9.sentence-1)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3384)

*Preconditions*: order ismemory_order​::​relaxed,memory_order​::​release, ormemory_order​::​seq_cst[.](#10.sentence-1)

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3391)

*Effects*: Atomically replaces the value referenced by *ptr with the value of desired[.](#11.sentence-1)

Memory is affected according to the value of order[.](#11.sentence-2)

[ð](#lib:operator=,atomic_ref)

`constexpr value_type operator=(value_type desired) const noexcept;
`

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3407)

*Constraints*: is_const_v<T> is false[.](#12.sentence-1)

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3411)

*Effects*: Equivalent to:store(desired);return desired;

[ð](#lib:load,atomic_ref)

`constexpr value_type load(memory_order order = memory_order::seq_cst) const noexcept;
`

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3429)

*Preconditions*: order ismemory_order​::​relaxed,memory_order​::​acquire, ormemory_order​::​seq_cst[.](#14.sentence-1)

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3436)

*Effects*: Memory is affected according to the value of order[.](#15.sentence-1)

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3440)

*Returns*: Atomically returns the value referenced by *ptr[.](#16.sentence-1)

[ð](#lib:operator_type,atomic_ref)

`constexpr operator value_type() const noexcept;
`

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3454)

*Effects*: Equivalent to: return load();

[ð](#lib:exchange,atomic_ref)

`constexpr value_type exchange(value_type desired,
                              memory_order order = memory_order::seq_cst) const noexcept;
`

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3469)

*Constraints*: is_const_v<T> is false[.](#18.sentence-1)

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3473)

*Effects*: Atomically replaces the value referenced by *ptr with desired[.](#19.sentence-1)

Memory is affected according to the value of order[.](#19.sentence-2)

This operation is an atomic read-modify-write operation ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#19.sentence-3)

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3480)

*Returns*: Atomically returns the value referenced by *ptr immediately before the effects[.](#20.sentence-1)

[ð](#lib:compare_exchange_weak,atomic_ref)

`constexpr bool compare_exchange_weak(value_type& expected, value_type desired,
                           memory_order success, memory_order failure) const noexcept;

constexpr bool compare_exchange_strong(value_type& expected, value_type desired,
                             memory_order success, memory_order failure) const noexcept;

constexpr bool compare_exchange_weak(value_type& expected, value_type desired,
                           memory_order order = memory_order::seq_cst) const noexcept;

constexpr bool compare_exchange_strong(value_type& expected, value_type desired,
                             memory_order order = memory_order::seq_cst) const noexcept;
`

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3509)

*Constraints*: is_const_v<T> is false[.](#21.sentence-1)

[22](#22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3513)

*Preconditions*: failure ismemory_order​::​relaxed,memory_order​::​acquire, ormemory_order​::​seq_cst[.](#22.sentence-1)

[23](#23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3520)

*Effects*: Retrieves the value in expected[.](#23.sentence-1)

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[.](#23.sentence-2)

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[.](#23.sentence-3)

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[.](#23.sentence-4)

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[.](#23.sentence-5)

If the operation returns true,
these operations are atomic read-modify-write operations ([[intro.races]](intro.races "6.10.2.2 Data races"))
on the value referenced by *ptr[.](#23.sentence-6)

Otherwise, these operations are atomic load operations on that memory[.](#23.sentence-7)

[24](#24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3549)

*Returns*: The result of the comparison[.](#24.sentence-1)

[25](#25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3553)

*Remarks*: A weak compare-and-exchange operation may fail spuriously[.](#25.sentence-1)

That is, even when the contents of memory referred to
by expected and ptr are equal,
it may return false and
store back to expected the same memory contents
that were originally there[.](#25.sentence-2)

[*Note [2](#note-2)*:

This spurious failure enables implementation of compare-and-exchange
on a broader class of machines, e.g., load-locked store-conditional machines[.](#25.sentence-3)

A consequence of spurious failure is
that nearly all uses of weak compare-and-exchange will be in a loop[.](#25.sentence-4)

When a compare-and-exchange is in a loop,
the weak version will yield better performance on some platforms[.](#25.sentence-5)

When a weak compare-and-exchange would require a loop and
a strong one would not, the strong one is preferable[.](#25.sentence-6)

â *end note*]

[ð](#lib:wait,atomic_ref%3cT%3e)

`constexpr void wait(value_type old, memory_order order = memory_order::seq_cst) const noexcept;
`

[26](#26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3579)

*Preconditions*: order ismemory_order​::​relaxed,memory_order​::​acquire, ormemory_order​::​seq_cst[.](#26.sentence-1)

[27](#27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3586)

*Effects*: Repeatedly performs the following steps, in order:

- [(27.1)](#27.1)

  Evaluates load(order) and
 compares its value representation for equality against that of old[.](#27.1.sentence-1)

- [(27.2)](#27.2)

  If they compare unequal, returns[.](#27.2.sentence-1)

- [(27.3)](#27.3)

  Blocks until it
 is unblocked by an atomic notifying operation or is unblocked spuriously[.](#27.3.sentence-1)

[28](#28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3600)

*Remarks*: This function is an atomic waiting operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))
on atomic object *ptr[.](#28.sentence-1)

[ð](#lib:notify_one,atomic_ref%3cT%3e)

`constexpr void notify_one() const noexcept;
`

[29](#29)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3612)

*Constraints*: is_const_v<T> is false[.](#29.sentence-1)

[30](#30)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3616)

*Effects*: Unblocks the execution of at least one atomic waiting operation on *ptr that is eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call,
if any such atomic waiting operations exist[.](#30.sentence-1)

[31](#31)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3622)

*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))
on atomic object *ptr[.](#31.sentence-1)

[ð](#lib:notify_all,atomic_ref%3cT%3e)

`constexpr void notify_all() const noexcept;
`

[32](#32)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3634)

*Constraints*: is_const_v<T> is false[.](#32.sentence-1)

[33](#33)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3638)

*Effects*: Unblocks the execution of all atomic waiting operations on *ptr that are eligible to be unblocked ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying")) by this call[.](#33.sentence-1)

[34](#34)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3643)

*Remarks*: This function is an atomic notifying operation ([[atomics.wait]](atomics.wait "32.5.6 Waiting and notifying"))
on atomic object *ptr[.](#34.sentence-1)

[ð](#lib:address,atomic_ref%3cT%3e)

`constexpr T* address() const noexcept;
`

[35](#35)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/threads.tex#L3655)

*Returns*: ptr[.](#35.sentence-1)
