[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;