[atomics.ref.pointer]

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

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

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

#### 32.5.7.5 Specialization for pointers [atomics.ref.pointer]

[1](#1)

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

There are specializations of the atomic_ref class template
for all pointer-to-object types[.](#1.sentence-1)

For each such type *pointer-type*,
the specialization atomic_ref<*pointer-type*> provides
additional atomic operations appropriate to pointer types[.](#1.sentence-2)

[2](#2)

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

The program is ill-formed
if is_always_lock_free is false andis_volatile_v<*pointer-type*> is true[.](#2.sentence-1)

namespace std {template<> struct atomic_ref<*pointer-type*> {private:*pointer-type** ptr; // *exposition only*public:using value_type = remove_cv_t<*pointer-type*>; using difference_type = ptrdiff_t; static constexpr size_t required_alignment = *implementation-defined*; static constexpr bool is_always_lock_free = *implementation-defined*; bool is_lock_free() const noexcept; constexpr explicit atomic_ref(*pointer-type*&); constexpr atomic_ref(const atomic_ref&) noexcept;
 atomic_ref& operator=(const atomic_ref&) = delete; constexpr void store(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr value_type operator=(value_type) const noexcept; constexpr value_type load(memory_order = memory_order::seq_cst) const noexcept; constexpr operator value_type() const noexcept; constexpr value_type exchange(value_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr bool compare_exchange_weak(value_type&, value_type,
 memory_order, memory_order) const noexcept; constexpr bool compare_exchange_strong(value_type&, value_type,
 memory_order, memory_order) const noexcept; constexpr bool compare_exchange_weak(value_type&, value_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr bool compare_exchange_strong(value_type&, value_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_add(difference_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_sub(difference_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_max(value_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr value_type fetch_min(value_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr void store_add(difference_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr void store_sub(difference_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr void store_max(value_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr void store_min(value_type,
 memory_order = memory_order::seq_cst) const noexcept; constexpr value_type operator++(int) const noexcept; constexpr value_type operator--(int) const noexcept; constexpr value_type operator++() const noexcept; constexpr value_type operator--() const noexcept; constexpr value_type operator+=(difference_type) const noexcept; constexpr value_type operator-=(difference_type) const noexcept; constexpr void wait(value_type, memory_order = memory_order::seq_cst) const noexcept; constexpr void notify_one() const noexcept; constexpr void notify_all() const noexcept; constexpr *pointer-type** address() const noexcept; };}

[3](#3)

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

Descriptions are provided below only for members
that differ from the primary template[.](#3.sentence-1)

[4](#4)

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

The following operations perform arithmetic computations[.](#4.sentence-1)

The correspondence among key, operator, and computation is specified
in Table [156](atomics.types.pointer#tab:atomic.types.pointer.comp "Table 156: Atomic pointer computations")[.](#4.sentence-2)

[ð](#lib:fetch_add,atomic_ref%3cpointer-type%3e)

`constexpr value_type fetch_key(difference_type operand,
                     memory_order order = memory_order::seq_cst) const noexcept;
`

[5](#5)

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

*Constraints*: is_const_v<*pointer-type*> is false[.](#5.sentence-1)

[6](#6)

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

*Mandates*: remove_pointer_t<*pointer-type*> is a complete object type[.](#6.sentence-1)

[7](#7)

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

*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[.](#7.sentence-1)

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

These operations are atomic read-modify-write operations ([[intro.races]](intro.races "6.10.2.2 Data races"))[.](#7.sentence-3)

[8](#8)

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

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

[9](#9)

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

*Remarks*: The result may be an undefined address,
but the operations otherwise have no undefined behavior[.](#9.sentence-1)

[10](#10)

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

For fetch_max and fetch_min, the maximum and minimum
computation is performed as if by max and min algorithms ([[alg.min.max]](alg.min.max "26.8.9 Minimum and maximum")), respectively, with the object value and the first
parameter as the arguments[.](#10.sentence-1)

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

If the pointers point to different complete objects (or subobjects thereof),
the < operator does not establish a strict weak ordering
(Table [29](utility.arg.requirements#tab:cpp17.lessthancomparable "Table 29: Cpp17LessThanComparable requirements"), [[expr.rel]](expr.rel "7.6.9 Relational operators"))[.](#10.sentence-2)

â *end note*]

[ð](#lib:store_add,atomic_ref%3cpointer-type%3e)

`constexpr void store_key(see above operand,
                     memory_order order = memory_order::seq_cst) const noexcept;
`

[11](#11)

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

*Mandates*: T is a complete object type[.](#11.sentence-1)

[12](#12)

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

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

[13](#13)

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

*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[.](#13.sentence-1)

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

These operations are atomic modify-write operations ([[atomics.order]](atomics.order "32.5.4 Order and consistency"))[.](#13.sentence-3)

[14](#14)

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

*Remarks*: The result may be an undefined address,
but the operations otherwise have no undefined behavior[.](#14.sentence-1)

For store_max and store_min,
the maximum and minimum computation is performed
as if by max and min algorithms ([[alg.min.max]](alg.min.max "26.8.9 Minimum and maximum")), respectively,
with *ptr and the first parameter as the arguments[.](#14.sentence-2)

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

If the pointers point to different complete objects (or subobjects thereof),
the < operator does not establish
a strict weak ordering (Table [29](utility.arg.requirements#tab:cpp17.lessthancomparable "Table 29: Cpp17LessThanComparable requirements"), [[expr.rel]](expr.rel "7.6.9 Relational operators"))[.](#14.sentence-3)

â *end note*]

[ð](#lib:operator+=,atomic_ref%3cpointer-type%3e)

`constexpr value_type operator op=(difference_type operand) const noexcept;
`

[15](#15)

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

*Constraints*: is_const_v<*pointer-type*> is false[.](#15.sentence-1)

[16](#16)

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

*Effects*: Equivalent to:return fetch_*key*(operand) *op* operand;
