[atomics.types.int]

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

## 32.5 Atomic operations [[atomics]](atomics#types.int)

### 32.5.8 Class template atomic [[atomics.types.generic]](atomics.types.generic#atomics.types.int)

#### 32.5.8.3 Specializations for integers [atomics.types.int]

[1](#1)

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

There are specializations of the atomic class template for the integral typeschar,signed char,unsigned char,short,unsigned short,int,unsigned int,long,unsigned long,long long,unsigned long long,char8_t,char16_t,char32_t,wchar_t,
and any other types needed by the typedefs in the header [<cstdint>](cstdint.syn#header:%3ccstdint%3e "17.4.1 Header <cstdint> synopsis [cstdint.syn]")[.](#1.sentence-1)

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

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

The specialization atomic<bool> uses the primary template ([[atomics.types.generic]](atomics.types.generic "32.5.8 Class template atomic"))[.](#1.sentence-3)

â *end note*]

namespace std {template<> struct atomic<*integral-type*> {using value_type = *integral-type*; using difference_type = value_type; static constexpr bool is_always_lock_free = *implementation-defined*; bool is_lock_free() const volatile noexcept; bool is_lock_free() const noexcept; constexpr atomic() noexcept; constexpr atomic(*integral-type*) noexcept;
 atomic(const atomic&) = delete;
 atomic& operator=(const atomic&) = delete;
 atomic& operator=(const atomic&) volatile = delete; void store(*integral-type*, memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store(*integral-type*, memory_order = memory_order::seq_cst) noexcept; *integral-type* operator=(*integral-type*) volatile noexcept; constexpr *integral-type* operator=(*integral-type*) noexcept; *integral-type* load(memory_order = memory_order::seq_cst) const volatile noexcept; constexpr *integral-type* load(memory_order = memory_order::seq_cst) const noexcept; operator *integral-type*() const volatile noexcept; constexpr operator *integral-type*() const noexcept; *integral-type* exchange(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr *integral-type* exchange(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_weak(*integral-type*&, *integral-type*,
 memory_order, memory_order) volatile noexcept; constexpr bool compare_exchange_weak(*integral-type*&, *integral-type*,
 memory_order, memory_order) noexcept; bool compare_exchange_strong(*integral-type*&, *integral-type*,
 memory_order, memory_order) volatile noexcept; constexpr bool compare_exchange_strong(*integral-type*&, *integral-type*,
 memory_order, memory_order) noexcept; bool compare_exchange_weak(*integral-type*&, *integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_weak(*integral-type*&, *integral-type*,
 memory_order = memory_order::seq_cst) noexcept; bool compare_exchange_strong(*integral-type*&, *integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr bool compare_exchange_strong(*integral-type*&, *integral-type*,
 memory_order = memory_order::seq_cst) noexcept; *integral-type* fetch_add(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr *integral-type* fetch_add(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; *integral-type* fetch_sub(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr *integral-type* fetch_sub(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; *integral-type* fetch_and(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr *integral-type* fetch_and(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; *integral-type* fetch_or(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr *integral-type* fetch_or(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; *integral-type* fetch_xor(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr *integral-type* fetch_xor(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; *integral-type* fetch_max(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr *integral-type* fetch_max(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; *integral-type* fetch_min(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr *integral-type* fetch_min(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; void store_add(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_add(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; void store_sub(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_sub(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; void store_and(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_and(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; void store_or(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_or(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; void store_xor(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_xor(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; void store_max(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_max(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; void store_min(*integral-type*,
 memory_order = memory_order::seq_cst) volatile noexcept; constexpr void store_min(*integral-type*,
 memory_order = memory_order::seq_cst) noexcept; *integral-type* operator++(int) volatile noexcept; constexpr *integral-type* operator++(int) noexcept; *integral-type* operator--(int) volatile noexcept; constexpr *integral-type* operator--(int) noexcept; *integral-type* operator++() volatile noexcept; constexpr *integral-type* operator++() noexcept; *integral-type* operator--() volatile noexcept; constexpr *integral-type* operator--() noexcept; *integral-type* operator+=(*integral-type*) volatile noexcept; constexpr *integral-type* operator+=(*integral-type*) noexcept; *integral-type* operator-=(*integral-type*) volatile noexcept; constexpr *integral-type* operator-=(*integral-type*) noexcept; *integral-type* operator&=(*integral-type*) volatile noexcept; constexpr *integral-type* operator&=(*integral-type*) noexcept; *integral-type* operator|=(*integral-type*) volatile noexcept; constexpr *integral-type* operator|=(*integral-type*) noexcept; *integral-type* operator^=(*integral-type*) volatile noexcept; constexpr *integral-type* operator^=(*integral-type*) noexcept; void wait(*integral-type*, memory_order = memory_order::seq_cst) const volatile noexcept; constexpr void wait(*integral-type*, memory_order = memory_order::seq_cst) const noexcept; void notify_one() volatile noexcept; constexpr void notify_one() noexcept; void notify_all() volatile noexcept; constexpr void notify_all() noexcept; };}

[2](#2)

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

The atomic integral specializations
are standard-layout structs[.](#2.sentence-1)

They each have
a trivial destructor[.](#2.sentence-2)

[3](#3)

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

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#L5180)

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

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

Table [155](#tab:atomic.types.int.comp) — Atomic arithmetic computations [[tab:atomic.types.int.comp]](./tab:atomic.types.int.comp)  

| [ð](#tab:atomic.types.int.comp-row-1)<br>***key*** | **Op** | **Computation** | ***key*** | **Op** | **Computation** |
| --- | --- | --- | --- | --- | --- |
| [ð](#tab:atomic.types.int.comp-row-2)<br>add | + | addition | and | & | bitwise and |
| [ð](#tab:atomic.types.int.comp-row-3)<br>sub | - | subtraction | or | | | bitwise inclusive or |
| [ð](#tab:atomic.types.int.comp-row-4)<br>max |  | maximum | xor | ^ | bitwise exclusive or |
| [ð](#tab:atomic.types.int.comp-row-5)<br>min |  | minimum |  |  |  |

[ð](#lib:atomic_fetch_add)

`integral-type fetch_key(integral-type operand,
                         memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr integral-type fetch_key(integral-type operand,
                                   memory_order order = memory_order::seq_cst) noexcept;
`

[5](#5)

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

*Constraints*: For the volatile overload of this function,is_always_lock_free is true[.](#5.sentence-1)

[6](#6)

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

*Effects*: Atomically replaces the value pointed to bythis with the result of the computation applied to the
value pointed to by this and the given operand[.](#6.sentence-1)

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

These operations are atomic read-modify-write operations ([[intro.multithread]](intro.multithread "6.10.2 Multi-threaded executions and data races"))[.](#6.sentence-3)

[7](#7)

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

*Returns*: Atomically, the value pointed to by this immediately before the effects[.](#7.sentence-1)

[8](#8)

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

*Remarks*: Except for fetch_max and fetch_min, 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[.](#8.sentence-1)

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

There are no undefined results arising from the computation[.](#8.sentence-2)

â *end note*]

[9](#9)

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

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

[ð](#lib:atomic_store_add)

`void store_key(integral-type operand,
                memory_order order = memory_order::seq_cst) volatile noexcept;
constexpr void store_key(integral-type operand,
                          memory_order order = memory_order::seq_cst) noexcept;
`

[10](#10)

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

*Constraints*: For the volatile overload of this function,is_always_lock_free is true[.](#10.sentence-1)

[11](#11)

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

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

[12](#12)

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

*Effects*: Atomically replaces the value pointed to by this with the result of the computation applied to
the value pointed to by this and the given operand[.](#12.sentence-1)

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

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

[13](#13)

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

*Remarks*: Except for store_max and store_min,
for signed integer types, the result is as if
the value pointed to by this and parameters
were converted to their corresponding unsigned types,
the computation performed on those types, and
the result converted back to the signed type[.](#13.sentence-1)

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

There are no undefined results arising from the computation[.](#13.sentence-2)

â *end note*]

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 the value pointed to by this and the first parameter as the arguments[.](#13.sentence-3)

[ð](#lib:operator+=,atomic%3cT*%3e)

`integral-type operator op=(integral-type operand) volatile noexcept;
constexpr integral-type operator op=(integral-type operand) noexcept;
`

[14](#14)

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

*Constraints*: For the volatile overload of this function,is_always_lock_free is true[.](#14.sentence-1)

[15](#15)

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

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