blob: 60057f1ebe331750b4011d5a1bacb5ba63fec786 [file] [log] [blame]
Howard Hinnant71be7292010-09-27 21:17:38 +00001// -*- C++ -*-
2//===--------------------------- atomic -----------------------------------===//
3//
Chandler Carruth7642bb12019-01-19 08:50:56 +00004// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Howard Hinnant71be7292010-09-27 21:17:38 +00007//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_ATOMIC
11#define _LIBCPP_ATOMIC
12
13/*
14 atomic synopsis
15
16namespace std
17{
18
JF Bastienfdb42c22016-03-25 15:48:21 +000019// feature test macro
20
21#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10
22
Howard Hinnant71be7292010-09-27 21:17:38 +000023// order and consistency
24
25typedef enum memory_order
26{
Howard Hinnantdca6e712010-09-28 17:13:38 +000027 memory_order_relaxed,
28 memory_order_consume, // load-consume
29 memory_order_acquire, // load-acquire
30 memory_order_release, // store-release
31 memory_order_acq_rel, // store-release load-acquire
32 memory_order_seq_cst // store-release load-acquire
Howard Hinnant71be7292010-09-27 21:17:38 +000033} memory_order;
34
Howard Hinnanteee2c142012-04-11 20:14:21 +000035template <class T> T kill_dependency(T y) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000036
37// lock-free property
38
Howard Hinnant931e3402013-01-21 20:39:41 +000039#define ATOMIC_BOOL_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000040#define ATOMIC_CHAR_LOCK_FREE unspecified
41#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
42#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
43#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
44#define ATOMIC_SHORT_LOCK_FREE unspecified
45#define ATOMIC_INT_LOCK_FREE unspecified
46#define ATOMIC_LONG_LOCK_FREE unspecified
47#define ATOMIC_LLONG_LOCK_FREE unspecified
Howard Hinnant931e3402013-01-21 20:39:41 +000048#define ATOMIC_POINTER_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000049
Howard Hinnant71be7292010-09-27 21:17:38 +000050// flag type and operations
51
52typedef struct atomic_flag
53{
Howard Hinnanteee2c142012-04-11 20:14:21 +000054 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
55 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
56 void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
57 void clear(memory_order m = memory_order_seq_cst) noexcept;
58 atomic_flag() noexcept = default;
Howard Hinnant71be7292010-09-27 21:17:38 +000059 atomic_flag(const atomic_flag&) = delete;
60 atomic_flag& operator=(const atomic_flag&) = delete;
61 atomic_flag& operator=(const atomic_flag&) volatile = delete;
62} atomic_flag;
63
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000064bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000065 atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000066
67bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000068 atomic_flag_test_and_set(atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000069
70bool
71 atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
Howard Hinnanteee2c142012-04-11 20:14:21 +000072 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000073
74bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000075 atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000076
77void
Howard Hinnanteee2c142012-04-11 20:14:21 +000078 atomic_flag_clear(volatile atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000079
80void
Howard Hinnanteee2c142012-04-11 20:14:21 +000081 atomic_flag_clear(atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000082
83void
Howard Hinnanteee2c142012-04-11 20:14:21 +000084 atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000085
86void
Howard Hinnanteee2c142012-04-11 20:14:21 +000087 atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000088
89#define ATOMIC_FLAG_INIT see below
Howard Hinnant493d1d92010-10-19 16:51:18 +000090#define ATOMIC_VAR_INIT(value) see below
Howard Hinnant71be7292010-09-27 21:17:38 +000091
Howard Hinnant71be7292010-09-27 21:17:38 +000092template <class T>
93struct atomic
94{
JF Bastienfdb42c22016-03-25 15:48:21 +000095 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +000096 bool is_lock_free() const volatile noexcept;
97 bool is_lock_free() const noexcept;
98 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
99 void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
100 T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
101 T load(memory_order m = memory_order_seq_cst) const noexcept;
102 operator T() const volatile noexcept;
103 operator T() const noexcept;
104 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
105 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000106 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000107 memory_order s, memory_order f) volatile noexcept;
108 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000109 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000110 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000111 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000112 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000113 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000114 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000115 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000116 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000117 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000118 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000119 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000120 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000121
Howard Hinnanteee2c142012-04-11 20:14:21 +0000122 atomic() noexcept = default;
123 constexpr atomic(T desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000124 atomic(const atomic&) = delete;
125 atomic& operator=(const atomic&) = delete;
126 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000127 T operator=(T) volatile noexcept;
128 T operator=(T) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000129};
130
131template <>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000132struct atomic<integral>
Howard Hinnant71be7292010-09-27 21:17:38 +0000133{
JF Bastienfdb42c22016-03-25 15:48:21 +0000134 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000135 bool is_lock_free() const volatile noexcept;
136 bool is_lock_free() const noexcept;
137 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
138 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
139 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
140 integral load(memory_order m = memory_order_seq_cst) const noexcept;
141 operator integral() const volatile noexcept;
142 operator integral() const noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000143 integral exchange(integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000144 memory_order m = memory_order_seq_cst) volatile noexcept;
145 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000146 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000147 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000148 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000149 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000150 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000151 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000152 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000153 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000154 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000155 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000156 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000157 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000158 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000159 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000160 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000161 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000162
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000163 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000164 fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
165 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000166 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000167 fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
168 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000169 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000170 fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
171 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000172 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000173 fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
174 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000175 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000176 fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
177 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000178
Howard Hinnanteee2c142012-04-11 20:14:21 +0000179 atomic() noexcept = default;
180 constexpr atomic(integral desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000181 atomic(const atomic&) = delete;
182 atomic& operator=(const atomic&) = delete;
183 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000184 integral operator=(integral desr) volatile noexcept;
185 integral operator=(integral desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000186
Howard Hinnanteee2c142012-04-11 20:14:21 +0000187 integral operator++(int) volatile noexcept;
188 integral operator++(int) noexcept;
189 integral operator--(int) volatile noexcept;
190 integral operator--(int) noexcept;
191 integral operator++() volatile noexcept;
192 integral operator++() noexcept;
193 integral operator--() volatile noexcept;
194 integral operator--() noexcept;
195 integral operator+=(integral op) volatile noexcept;
196 integral operator+=(integral op) noexcept;
197 integral operator-=(integral op) volatile noexcept;
198 integral operator-=(integral op) noexcept;
199 integral operator&=(integral op) volatile noexcept;
200 integral operator&=(integral op) noexcept;
201 integral operator|=(integral op) volatile noexcept;
202 integral operator|=(integral op) noexcept;
203 integral operator^=(integral op) volatile noexcept;
204 integral operator^=(integral op) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000205};
206
207template <class T>
208struct atomic<T*>
Howard Hinnant71be7292010-09-27 21:17:38 +0000209{
JF Bastienfdb42c22016-03-25 15:48:21 +0000210 static constexpr bool is_always_lock_free;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000211 bool is_lock_free() const volatile noexcept;
212 bool is_lock_free() const noexcept;
213 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
214 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
215 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
216 T* load(memory_order m = memory_order_seq_cst) const noexcept;
217 operator T*() const volatile noexcept;
218 operator T*() const noexcept;
219 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
220 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000221 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000222 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000223 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000224 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000225 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000226 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000227 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000228 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000229 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000230 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000231 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000232 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000233 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000234 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000235 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000236 memory_order m = memory_order_seq_cst) noexcept;
237 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
238 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
239 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
240 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000241
Howard Hinnanteee2c142012-04-11 20:14:21 +0000242 atomic() noexcept = default;
243 constexpr atomic(T* desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000244 atomic(const atomic&) = delete;
245 atomic& operator=(const atomic&) = delete;
246 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000247
Howard Hinnanteee2c142012-04-11 20:14:21 +0000248 T* operator=(T*) volatile noexcept;
249 T* operator=(T*) noexcept;
250 T* operator++(int) volatile noexcept;
251 T* operator++(int) noexcept;
252 T* operator--(int) volatile noexcept;
253 T* operator--(int) noexcept;
254 T* operator++() volatile noexcept;
255 T* operator++() noexcept;
256 T* operator--() volatile noexcept;
257 T* operator--() noexcept;
258 T* operator+=(ptrdiff_t op) volatile noexcept;
259 T* operator+=(ptrdiff_t op) noexcept;
260 T* operator-=(ptrdiff_t op) volatile noexcept;
261 T* operator-=(ptrdiff_t op) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000262};
263
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000264
265template <class T>
266 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000267 atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000268
269template <class T>
270 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000271 atomic_is_lock_free(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000272
273template <class T>
274 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000275 atomic_init(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000276
277template <class T>
278 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000279 atomic_init(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000280
281template <class T>
282 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000283 atomic_store(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000284
285template <class T>
286 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000287 atomic_store(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000288
289template <class T>
290 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000291 atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000292
293template <class T>
294 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000295 atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000296
297template <class T>
298 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000299 atomic_load(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000300
301template <class T>
302 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000303 atomic_load(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000304
305template <class T>
306 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000307 atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000308
309template <class T>
310 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000311 atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000312
313template <class T>
314 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000315 atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000316
317template <class T>
318 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000319 atomic_exchange(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000320
321template <class T>
322 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000323 atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000324
325template <class T>
326 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000327 atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000328
329template <class T>
330 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000331 atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000332
333template <class T>
334 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000335 atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000336
337template <class T>
338 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000339 atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000340
341template <class T>
342 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000343 atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000344
345template <class T>
346 bool
347 atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
348 T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000349 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000350
351template <class T>
352 bool
353 atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000354 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000355
356template <class T>
357 bool
358 atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
359 T* expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000360 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000361
362template <class T>
363 bool
364 atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
365 T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000366 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000367
368template <class Integral>
369 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000370 atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000371
372template <class Integral>
373 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000374 atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000375
376template <class Integral>
377 Integral
378 atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000379 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000380template <class Integral>
381 Integral
382 atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000383 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000384template <class Integral>
385 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000386 atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000387
388template <class Integral>
389 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000390 atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000391
392template <class Integral>
393 Integral
394 atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000395 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000396template <class Integral>
397 Integral
398 atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000399 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000400template <class Integral>
401 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000402 atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000403
404template <class Integral>
405 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000406 atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000407
408template <class Integral>
409 Integral
410 atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000411 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000412template <class Integral>
413 Integral
414 atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000415 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000416template <class Integral>
417 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000418 atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000419
420template <class Integral>
421 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000422 atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000423
424template <class Integral>
425 Integral
426 atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000427 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000428template <class Integral>
429 Integral
430 atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000431 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000432template <class Integral>
433 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000434 atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000435
436template <class Integral>
437 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000438 atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000439
440template <class Integral>
441 Integral
442 atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000443 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000444template <class Integral>
445 Integral
446 atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000447 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000448
449template <class T>
450 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000451 atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000452
453template <class T>
454 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000455 atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000456
457template <class T>
458 T*
459 atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000460 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000461template <class T>
462 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000463 atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000464
465template <class T>
466 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000467 atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000468
469template <class T>
470 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000471 atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000472
473template <class T>
474 T*
475 atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000476 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000477template <class T>
478 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000479 atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000480
481// Atomics for standard typedef types
482
Howard Hinnantf0af8d92013-01-04 18:58:50 +0000483typedef atomic<bool> atomic_bool;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000484typedef atomic<char> atomic_char;
485typedef atomic<signed char> atomic_schar;
486typedef atomic<unsigned char> atomic_uchar;
487typedef atomic<short> atomic_short;
488typedef atomic<unsigned short> atomic_ushort;
489typedef atomic<int> atomic_int;
490typedef atomic<unsigned int> atomic_uint;
491typedef atomic<long> atomic_long;
492typedef atomic<unsigned long> atomic_ulong;
493typedef atomic<long long> atomic_llong;
494typedef atomic<unsigned long long> atomic_ullong;
495typedef atomic<char16_t> atomic_char16_t;
496typedef atomic<char32_t> atomic_char32_t;
497typedef atomic<wchar_t> atomic_wchar_t;
498
499typedef atomic<int_least8_t> atomic_int_least8_t;
500typedef atomic<uint_least8_t> atomic_uint_least8_t;
501typedef atomic<int_least16_t> atomic_int_least16_t;
502typedef atomic<uint_least16_t> atomic_uint_least16_t;
503typedef atomic<int_least32_t> atomic_int_least32_t;
504typedef atomic<uint_least32_t> atomic_uint_least32_t;
505typedef atomic<int_least64_t> atomic_int_least64_t;
506typedef atomic<uint_least64_t> atomic_uint_least64_t;
507
508typedef atomic<int_fast8_t> atomic_int_fast8_t;
509typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
510typedef atomic<int_fast16_t> atomic_int_fast16_t;
511typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
512typedef atomic<int_fast32_t> atomic_int_fast32_t;
513typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
514typedef atomic<int_fast64_t> atomic_int_fast64_t;
515typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
516
Marshall Clowf710afc2016-06-30 15:28:38 +0000517typedef atomic<int8_t> atomic_int8_t;
518typedef atomic<uint8_t> atomic_uint8_t;
519typedef atomic<int16_t> atomic_int16_t;
520typedef atomic<uint16_t> atomic_uint16_t;
521typedef atomic<int32_t> atomic_int32_t;
522typedef atomic<uint32_t> atomic_uint32_t;
523typedef atomic<int64_t> atomic_int64_t;
524typedef atomic<uint64_t> atomic_uint64_t;
525
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000526typedef atomic<intptr_t> atomic_intptr_t;
527typedef atomic<uintptr_t> atomic_uintptr_t;
528typedef atomic<size_t> atomic_size_t;
529typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
530typedef atomic<intmax_t> atomic_intmax_t;
531typedef atomic<uintmax_t> atomic_uintmax_t;
532
Howard Hinnant71be7292010-09-27 21:17:38 +0000533// fences
534
Howard Hinnanteee2c142012-04-11 20:14:21 +0000535void atomic_thread_fence(memory_order m) noexcept;
536void atomic_signal_fence(memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000537
538} // std
539
540*/
541
542#include <__config>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000543#include <cstddef>
544#include <cstdint>
545#include <type_traits>
Marshall Clow0a1e7502018-09-12 19:41:40 +0000546#include <version>
Howard Hinnant71be7292010-09-27 21:17:38 +0000547
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000548#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant71be7292010-09-27 21:17:38 +0000549#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000550#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000551
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000552#ifdef _LIBCPP_HAS_NO_THREADS
553#error <atomic> is not supported on this single threaded system
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000554#endif
555#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
556#error <atomic> is not implemented
557#endif
Volodymyr Sapsaif3ed1fd2018-05-15 22:38:31 +0000558#ifdef kill_dependency
559#error C++ standard library is incompatible with <stdatomic.h>
560#endif
Jonathan Roelofs39cb6bf2014-09-05 19:45:05 +0000561
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000562#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
563 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
564 __m == memory_order_acquire || \
565 __m == memory_order_acq_rel, \
566 "memory order argument to atomic operation is invalid")
567
568#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
569 _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
570 __m == memory_order_acq_rel, \
571 "memory order argument to atomic operation is invalid")
572
573#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
574 _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
575 __f == memory_order_acq_rel, \
576 "memory order argument to atomic operation is invalid")
577
Howard Hinnant71be7292010-09-27 21:17:38 +0000578_LIBCPP_BEGIN_NAMESPACE_STD
579
Howard Hinnantdca6e712010-09-28 17:13:38 +0000580typedef enum memory_order
581{
582 memory_order_relaxed, memory_order_consume, memory_order_acquire,
583 memory_order_release, memory_order_acq_rel, memory_order_seq_cst
584} memory_order;
585
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000586#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
Dan Albert7b65ace2014-08-09 23:51:51 +0000587namespace __gcc_atomic {
Marshall Clow290eb3f2015-01-11 06:15:59 +0000588template <typename _Tp>
Dan Albert7b65ace2014-08-09 23:51:51 +0000589struct __gcc_atomic_t {
Eric Fiselier88f07122015-12-15 00:32:21 +0000590
591#if _GNUC_VER >= 501
592 static_assert(is_trivially_copyable<_Tp>::value,
593 "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
594#endif
595
Eric Fiselier684aaca2015-10-14 08:36:22 +0000596 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000597#ifndef _LIBCPP_CXX03_LANG
Eric Fiselier684aaca2015-10-14 08:36:22 +0000598 __gcc_atomic_t() _NOEXCEPT = default;
599#else
600 __gcc_atomic_t() _NOEXCEPT : __a_value() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000601#endif // _LIBCPP_CXX03_LANG
Eric Fiselier719e0442015-07-14 17:50:27 +0000602 _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT
603 : __a_value(value) {}
Marshall Clow290eb3f2015-01-11 06:15:59 +0000604 _Tp __a_value;
Dan Albert7b65ace2014-08-09 23:51:51 +0000605};
606#define _Atomic(x) __gcc_atomic::__gcc_atomic_t<x>
607
Marshall Clow290eb3f2015-01-11 06:15:59 +0000608template <typename _Tp> _Tp __create();
Dan Albert7b65ace2014-08-09 23:51:51 +0000609
Marshall Clow290eb3f2015-01-11 06:15:59 +0000610template <typename _Tp, typename _Td>
611typename enable_if<sizeof(_Tp()->__a_value = __create<_Td>()), char>::type
Dan Albert7b65ace2014-08-09 23:51:51 +0000612 __test_atomic_assignable(int);
Marshall Clow290eb3f2015-01-11 06:15:59 +0000613template <typename _Tp, typename _Up>
Dan Albert7b65ace2014-08-09 23:51:51 +0000614__two __test_atomic_assignable(...);
615
Marshall Clow290eb3f2015-01-11 06:15:59 +0000616template <typename _Tp, typename _Td>
Dan Albert7b65ace2014-08-09 23:51:51 +0000617struct __can_assign {
618 static const bool value =
Marshall Clow290eb3f2015-01-11 06:15:59 +0000619 sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char);
Dan Albert7b65ace2014-08-09 23:51:51 +0000620};
621
Eric Fiselier684aaca2015-10-14 08:36:22 +0000622static inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000623 // Avoid switch statement to make this a constexpr.
624 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
625 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
626 (__order == memory_order_release ? __ATOMIC_RELEASE:
627 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
628 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
629 __ATOMIC_CONSUME))));
630}
631
Eric Fiselier684aaca2015-10-14 08:36:22 +0000632static inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000633 // Avoid switch statement to make this a constexpr.
634 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
635 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
636 (__order == memory_order_release ? __ATOMIC_RELAXED:
637 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
638 (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
639 __ATOMIC_CONSUME))));
640}
641
Dan Albert7b65ace2014-08-09 23:51:51 +0000642} // namespace __gcc_atomic
643
644template <typename _Tp>
645static inline
646typename enable_if<
647 __gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value>::type
JF Bastien6e412d92018-05-26 19:44:45 +0000648__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000649 __a->__a_value = __val;
650}
651
652template <typename _Tp>
653static inline
654typename enable_if<
655 !__gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value &&
656 __gcc_atomic::__can_assign< _Atomic(_Tp)*, _Tp>::value>::type
JF Bastien6e412d92018-05-26 19:44:45 +0000657__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000658 // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
659 // the default operator= in an object is not volatile, a byte-by-byte copy
660 // is required.
661 volatile char* to = reinterpret_cast<volatile char*>(&__a->__a_value);
662 volatile char* end = to + sizeof(_Tp);
663 char* from = reinterpret_cast<char*>(&__val);
664 while (to != end) {
665 *to++ = *from++;
666 }
667}
668
669template <typename _Tp>
JF Bastien6e412d92018-05-26 19:44:45 +0000670static inline void __c11_atomic_init(_Atomic(_Tp)* __a, _Tp __val) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000671 __a->__a_value = __val;
672}
673
674static inline void __c11_atomic_thread_fence(memory_order __order) {
675 __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order));
676}
677
678static inline void __c11_atomic_signal_fence(memory_order __order) {
679 __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order));
680}
681
Dan Albert7b65ace2014-08-09 23:51:51 +0000682template <typename _Tp>
683static inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a, _Tp __val,
JF Bastien6e412d92018-05-26 19:44:45 +0000684 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000685 return __atomic_store(&__a->__a_value, &__val,
686 __gcc_atomic::__to_gcc_order(__order));
687}
688
689template <typename _Tp>
690static inline void __c11_atomic_store(_Atomic(_Tp)* __a, _Tp __val,
JF Bastien6e412d92018-05-26 19:44:45 +0000691 memory_order __order) {
Dan Albert48815f22015-01-06 18:39:37 +0000692 __atomic_store(&__a->__a_value, &__val,
693 __gcc_atomic::__to_gcc_order(__order));
Dan Albert7b65ace2014-08-09 23:51:51 +0000694}
695
696template <typename _Tp>
JF Bastien663d0452018-06-01 18:02:53 +0000697static inline _Tp __c11_atomic_load(const volatile _Atomic(_Tp)* __a,
JF Bastien6e412d92018-05-26 19:44:45 +0000698 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000699 _Tp __ret;
700 __atomic_load(&__a->__a_value, &__ret,
701 __gcc_atomic::__to_gcc_order(__order));
702 return __ret;
703}
704
705template <typename _Tp>
JF Bastien663d0452018-06-01 18:02:53 +0000706static inline _Tp __c11_atomic_load(const _Atomic(_Tp)* __a, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000707 _Tp __ret;
708 __atomic_load(&__a->__a_value, &__ret,
709 __gcc_atomic::__to_gcc_order(__order));
710 return __ret;
711}
712
713template <typename _Tp>
714static inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a,
JF Bastien6e412d92018-05-26 19:44:45 +0000715 _Tp __value, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000716 _Tp __ret;
717 __atomic_exchange(&__a->__a_value, &__value, &__ret,
718 __gcc_atomic::__to_gcc_order(__order));
719 return __ret;
720}
721
722template <typename _Tp>
723static inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000724 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000725 _Tp __ret;
726 __atomic_exchange(&__a->__a_value, &__value, &__ret,
727 __gcc_atomic::__to_gcc_order(__order));
728 return __ret;
729}
730
731template <typename _Tp>
732static inline bool __c11_atomic_compare_exchange_strong(
733 volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000734 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000735 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
736 false,
737 __gcc_atomic::__to_gcc_order(__success),
Dan Albert48815f22015-01-06 18:39:37 +0000738 __gcc_atomic::__to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000739}
740
741template <typename _Tp>
742static inline bool __c11_atomic_compare_exchange_strong(
743 _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000744 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000745 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
746 false,
747 __gcc_atomic::__to_gcc_order(__success),
Dan Albert48815f22015-01-06 18:39:37 +0000748 __gcc_atomic::__to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000749}
750
751template <typename _Tp>
752static inline bool __c11_atomic_compare_exchange_weak(
753 volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
JF Bastien6e412d92018-05-26 19:44:45 +0000754 memory_order __success, memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000755 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
756 true,
757 __gcc_atomic::__to_gcc_order(__success),
Dan Albert48815f22015-01-06 18:39:37 +0000758 __gcc_atomic::__to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000759}
760
761template <typename _Tp>
762static inline bool __c11_atomic_compare_exchange_weak(
763 _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
JF Bastien6e412d92018-05-26 19:44:45 +0000764 memory_order __failure) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000765 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
766 true,
767 __gcc_atomic::__to_gcc_order(__success),
Dan Albert48815f22015-01-06 18:39:37 +0000768 __gcc_atomic::__to_gcc_failure_order(__failure));
Dan Albert7b65ace2014-08-09 23:51:51 +0000769}
770
771template <typename _Tp>
772struct __skip_amt { enum {value = 1}; };
773
774template <typename _Tp>
775struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
776
777// FIXME: Haven't figured out what the spec says about using arrays with
778// atomic_fetch_add. Force a failure rather than creating bad behavior.
779template <typename _Tp>
780struct __skip_amt<_Tp[]> { };
781template <typename _Tp, int n>
782struct __skip_amt<_Tp[n]> { };
783
784template <typename _Tp, typename _Td>
785static inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a,
JF Bastien6e412d92018-05-26 19:44:45 +0000786 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000787 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
788 __gcc_atomic::__to_gcc_order(__order));
789}
790
791template <typename _Tp, typename _Td>
792static inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta,
JF Bastien6e412d92018-05-26 19:44:45 +0000793 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000794 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
795 __gcc_atomic::__to_gcc_order(__order));
796}
797
798template <typename _Tp, typename _Td>
799static inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a,
JF Bastien6e412d92018-05-26 19:44:45 +0000800 _Td __delta, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000801 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
802 __gcc_atomic::__to_gcc_order(__order));
803}
804
805template <typename _Tp, typename _Td>
806static inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta,
JF Bastien6e412d92018-05-26 19:44:45 +0000807 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000808 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
809 __gcc_atomic::__to_gcc_order(__order));
810}
811
812template <typename _Tp>
813static inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a,
JF Bastien6e412d92018-05-26 19:44:45 +0000814 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000815 return __atomic_fetch_and(&__a->__a_value, __pattern,
816 __gcc_atomic::__to_gcc_order(__order));
817}
818
819template <typename _Tp>
820static inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a,
JF Bastien6e412d92018-05-26 19:44:45 +0000821 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000822 return __atomic_fetch_and(&__a->__a_value, __pattern,
823 __gcc_atomic::__to_gcc_order(__order));
824}
825
826template <typename _Tp>
827static inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a,
JF Bastien6e412d92018-05-26 19:44:45 +0000828 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000829 return __atomic_fetch_or(&__a->__a_value, __pattern,
830 __gcc_atomic::__to_gcc_order(__order));
831}
832
833template <typename _Tp>
834static inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern,
JF Bastien6e412d92018-05-26 19:44:45 +0000835 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000836 return __atomic_fetch_or(&__a->__a_value, __pattern,
837 __gcc_atomic::__to_gcc_order(__order));
838}
839
840template <typename _Tp>
841static inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a,
JF Bastien6e412d92018-05-26 19:44:45 +0000842 _Tp __pattern, memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000843 return __atomic_fetch_xor(&__a->__a_value, __pattern,
844 __gcc_atomic::__to_gcc_order(__order));
845}
846
847template <typename _Tp>
848static inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern,
JF Bastien6e412d92018-05-26 19:44:45 +0000849 memory_order __order) {
Dan Albert7b65ace2014-08-09 23:51:51 +0000850 return __atomic_fetch_xor(&__a->__a_value, __pattern,
851 __gcc_atomic::__to_gcc_order(__order));
852}
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000853#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP
Dan Albert7b65ace2014-08-09 23:51:51 +0000854
Howard Hinnantdca6e712010-09-28 17:13:38 +0000855template <class _Tp>
856inline _LIBCPP_INLINE_VISIBILITY
857_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +0000858kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +0000859{
860 return __y;
861}
Howard Hinnant71be7292010-09-27 21:17:38 +0000862
Eric Fiselierbed42df2017-04-20 23:22:46 +0000863#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
864# define ATOMIC_BOOL_LOCK_FREE __CLANG_ATOMIC_BOOL_LOCK_FREE
865# define ATOMIC_CHAR_LOCK_FREE __CLANG_ATOMIC_CHAR_LOCK_FREE
866# define ATOMIC_CHAR16_T_LOCK_FREE __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
867# define ATOMIC_CHAR32_T_LOCK_FREE __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
868# define ATOMIC_WCHAR_T_LOCK_FREE __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
869# define ATOMIC_SHORT_LOCK_FREE __CLANG_ATOMIC_SHORT_LOCK_FREE
870# define ATOMIC_INT_LOCK_FREE __CLANG_ATOMIC_INT_LOCK_FREE
871# define ATOMIC_LONG_LOCK_FREE __CLANG_ATOMIC_LONG_LOCK_FREE
872# define ATOMIC_LLONG_LOCK_FREE __CLANG_ATOMIC_LLONG_LOCK_FREE
873# define ATOMIC_POINTER_LOCK_FREE __CLANG_ATOMIC_POINTER_LOCK_FREE
874#else
875# define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
876# define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
877# define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
878# define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
879# define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
880# define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
881# define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
882# define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
883# define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
884# define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
885#endif
JF Bastienfdb42c22016-03-25 15:48:21 +0000886
Howard Hinnant138f5922010-12-07 20:46:14 +0000887// general atomic<T>
888
889template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
890struct __atomic_base // false
891{
Howard Hinnantd5eebd62012-09-16 20:33:09 +0000892 mutable _Atomic(_Tp) __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +0000893
JF Bastienfdb42c22016-03-25 15:48:21 +0000894#if defined(__cpp_lib_atomic_is_always_lock_free)
895 static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
896#endif
897
Howard Hinnant138f5922010-12-07 20:46:14 +0000898 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000899 bool is_lock_free() const volatile _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +0000900 {
Eric Fiselier8020b6c2015-08-19 17:21:46 +0000901#if defined(_LIBCPP_HAS_C_ATOMIC_IMP)
Eric Fiselier3fd22c22015-06-13 00:23:07 +0000902 return __c11_atomic_is_lock_free(sizeof(_Tp));
903#else
904 return __atomic_is_lock_free(sizeof(_Tp), 0);
905#endif
906 }
Howard Hinnant138f5922010-12-07 20:46:14 +0000907 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000908 bool is_lock_free() const _NOEXCEPT
Eric Fiselier3fd22c22015-06-13 00:23:07 +0000909 {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
Howard Hinnant138f5922010-12-07 20:46:14 +0000910 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000911 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000912 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Richard Smith27a4a972012-04-11 18:55:46 +0000913 {__c11_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000914 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000915 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000916 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Richard Smith27a4a972012-04-11 18:55:46 +0000917 {__c11_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000918 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000919 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000920 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Richard Smith27a4a972012-04-11 18:55:46 +0000921 {return __c11_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000922 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000923 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000924 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Richard Smith27a4a972012-04-11 18:55:46 +0000925 {return __c11_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000926 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000927 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +0000928 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000929 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +0000930 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000931 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000932 {return __c11_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000933 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000934 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000935 {return __c11_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000936 _LIBCPP_INLINE_VISIBILITY
937 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000938 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000939 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Richard Smith27a4a972012-04-11 18:55:46 +0000940 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000941 _LIBCPP_INLINE_VISIBILITY
942 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000943 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000944 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Richard Smith27a4a972012-04-11 18:55:46 +0000945 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000946 _LIBCPP_INLINE_VISIBILITY
947 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000948 memory_order __s, memory_order __f) volatile _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000949 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Richard Smith27a4a972012-04-11 18:55:46 +0000950 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000951 _LIBCPP_INLINE_VISIBILITY
952 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000953 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +0000954 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Richard Smith27a4a972012-04-11 18:55:46 +0000955 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000956 _LIBCPP_INLINE_VISIBILITY
957 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000958 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000959 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000960 _LIBCPP_INLINE_VISIBILITY
961 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000962 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000963 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000964 _LIBCPP_INLINE_VISIBILITY
965 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000966 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000967 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000968 _LIBCPP_INLINE_VISIBILITY
969 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000970 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000971 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000972
973 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +0000974#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3d284222013-05-02 20:18:43 +0000975 __atomic_base() _NOEXCEPT = default;
976#else
977 __atomic_base() _NOEXCEPT : __a_() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +0000978#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3d284222013-05-02 20:18:43 +0000979
Howard Hinnant138f5922010-12-07 20:46:14 +0000980 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000981 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
Eric Fiselier2d8515f2017-01-06 20:58:25 +0000982#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant138f5922010-12-07 20:46:14 +0000983 __atomic_base(const __atomic_base&) = delete;
984 __atomic_base& operator=(const __atomic_base&) = delete;
985 __atomic_base& operator=(const __atomic_base&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +0000986#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +0000987private:
988 __atomic_base(const __atomic_base&);
989 __atomic_base& operator=(const __atomic_base&);
990 __atomic_base& operator=(const __atomic_base&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +0000991#endif
Howard Hinnant138f5922010-12-07 20:46:14 +0000992};
993
JF Bastienfdb42c22016-03-25 15:48:21 +0000994#if defined(__cpp_lib_atomic_is_always_lock_free)
995template <class _Tp, bool __b>
996_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
997#endif
998
Howard Hinnant138f5922010-12-07 20:46:14 +0000999// atomic<Integral>
1000
1001template <class _Tp>
1002struct __atomic_base<_Tp, true>
1003 : public __atomic_base<_Tp, false>
1004{
1005 typedef __atomic_base<_Tp, false> __base;
1006 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001007 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001008 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001009 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001010
1011 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001012 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001013 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001014 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001015 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001016 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001017 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001018 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001019 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001020 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001021 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001022 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001023 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001024 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001025 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001026 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001027 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001028 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001029 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001030 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001031 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001032 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001033 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001034 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001035 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001036 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001037 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001038 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001039 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001040 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001041
1042 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001043 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001044 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001045 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001046 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001047 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001048 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001049 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +00001050 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001051 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001052 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001053 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001054 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001055 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001056 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001057 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001058 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001059 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001060 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001061 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001062 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001063 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001064 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001065 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001066 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001067 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001068 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001069 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001070 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001071 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001072 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001073 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001074 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001075 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001076 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001077 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001078};
1079
1080// atomic<T>
1081
1082template <class _Tp>
1083struct atomic
1084 : public __atomic_base<_Tp>
1085{
1086 typedef __atomic_base<_Tp> __base;
1087 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001088 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001089 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001090 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001091
1092 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001093 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001094 {__base::store(__d); return __d;}
1095 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001096 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001097 {__base::store(__d); return __d;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001098};
1099
1100// atomic<T*>
1101
1102template <class _Tp>
1103struct atomic<_Tp*>
1104 : public __atomic_base<_Tp*>
1105{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001106 typedef __atomic_base<_Tp*> __base;
Howard Hinnant138f5922010-12-07 20:46:14 +00001107 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001108 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001109 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001110 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001111
1112 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001113 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001114 {__base::store(__d); return __d;}
1115 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001116 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001117 {__base::store(__d); return __d;}
1118
1119 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001120 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001121 volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001122 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001123 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001124 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001125 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001126 _LIBCPP_INLINE_VISIBILITY
1127 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001128 volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001129 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001130 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001131 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001132 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001133
1134 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001135 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001136 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001137 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001138 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001139 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001140 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001141 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001142 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001143 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001144 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001145 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001146 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001147 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001148 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001149 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001150 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001151 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001152 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001153 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001154 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001155 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001156 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001157 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001158};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001159
1160// atomic_is_lock_free
1161
1162template <class _Tp>
1163inline _LIBCPP_INLINE_VISIBILITY
1164bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001165atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001166{
Howard Hinnant138f5922010-12-07 20:46:14 +00001167 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001168}
1169
1170template <class _Tp>
1171inline _LIBCPP_INLINE_VISIBILITY
1172bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001173atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001174{
Howard Hinnant138f5922010-12-07 20:46:14 +00001175 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001176}
1177
1178// atomic_init
1179
1180template <class _Tp>
1181inline _LIBCPP_INLINE_VISIBILITY
1182void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001183atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001184{
Richard Smith27a4a972012-04-11 18:55:46 +00001185 __c11_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001186}
1187
1188template <class _Tp>
1189inline _LIBCPP_INLINE_VISIBILITY
1190void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001191atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001192{
Richard Smith27a4a972012-04-11 18:55:46 +00001193 __c11_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001194}
1195
1196// atomic_store
1197
1198template <class _Tp>
1199inline _LIBCPP_INLINE_VISIBILITY
1200void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001201atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001202{
Howard Hinnant138f5922010-12-07 20:46:14 +00001203 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001204}
1205
1206template <class _Tp>
1207inline _LIBCPP_INLINE_VISIBILITY
1208void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001209atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001210{
Howard Hinnant138f5922010-12-07 20:46:14 +00001211 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001212}
1213
1214// atomic_store_explicit
1215
1216template <class _Tp>
1217inline _LIBCPP_INLINE_VISIBILITY
1218void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001219atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001220 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001221{
Howard Hinnant138f5922010-12-07 20:46:14 +00001222 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001223}
1224
1225template <class _Tp>
1226inline _LIBCPP_INLINE_VISIBILITY
1227void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001228atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001229 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001230{
Howard Hinnant138f5922010-12-07 20:46:14 +00001231 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001232}
1233
1234// atomic_load
1235
1236template <class _Tp>
1237inline _LIBCPP_INLINE_VISIBILITY
1238_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001239atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001240{
Howard Hinnant138f5922010-12-07 20:46:14 +00001241 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001242}
1243
1244template <class _Tp>
1245inline _LIBCPP_INLINE_VISIBILITY
1246_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001247atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001248{
Howard Hinnant138f5922010-12-07 20:46:14 +00001249 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001250}
1251
1252// atomic_load_explicit
1253
1254template <class _Tp>
1255inline _LIBCPP_INLINE_VISIBILITY
1256_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001257atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001258 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001259{
Howard Hinnant138f5922010-12-07 20:46:14 +00001260 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001261}
1262
1263template <class _Tp>
1264inline _LIBCPP_INLINE_VISIBILITY
1265_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001266atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001267 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001268{
Howard Hinnant138f5922010-12-07 20:46:14 +00001269 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001270}
1271
1272// atomic_exchange
1273
1274template <class _Tp>
1275inline _LIBCPP_INLINE_VISIBILITY
1276_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001277atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001278{
Howard Hinnant138f5922010-12-07 20:46:14 +00001279 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001280}
1281
1282template <class _Tp>
1283inline _LIBCPP_INLINE_VISIBILITY
1284_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001285atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001286{
Howard Hinnant138f5922010-12-07 20:46:14 +00001287 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001288}
1289
1290// atomic_exchange_explicit
1291
1292template <class _Tp>
1293inline _LIBCPP_INLINE_VISIBILITY
1294_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001295atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001296{
Howard Hinnant138f5922010-12-07 20:46:14 +00001297 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001298}
1299
1300template <class _Tp>
1301inline _LIBCPP_INLINE_VISIBILITY
1302_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001303atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001304{
Howard Hinnant138f5922010-12-07 20:46:14 +00001305 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001306}
1307
1308// atomic_compare_exchange_weak
1309
1310template <class _Tp>
1311inline _LIBCPP_INLINE_VISIBILITY
1312bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001313atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001314{
Howard Hinnant138f5922010-12-07 20:46:14 +00001315 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001316}
1317
1318template <class _Tp>
1319inline _LIBCPP_INLINE_VISIBILITY
1320bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001321atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001322{
Howard Hinnant138f5922010-12-07 20:46:14 +00001323 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001324}
1325
1326// atomic_compare_exchange_strong
1327
1328template <class _Tp>
1329inline _LIBCPP_INLINE_VISIBILITY
1330bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001331atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001332{
Howard Hinnant138f5922010-12-07 20:46:14 +00001333 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001334}
1335
1336template <class _Tp>
1337inline _LIBCPP_INLINE_VISIBILITY
1338bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001339atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001340{
Howard Hinnant138f5922010-12-07 20:46:14 +00001341 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001342}
1343
1344// atomic_compare_exchange_weak_explicit
1345
1346template <class _Tp>
1347inline _LIBCPP_INLINE_VISIBILITY
1348bool
1349atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
1350 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001351 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001352 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001353{
Howard Hinnant138f5922010-12-07 20:46:14 +00001354 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001355}
1356
1357template <class _Tp>
1358inline _LIBCPP_INLINE_VISIBILITY
1359bool
1360atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001361 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001362 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001363{
Howard Hinnant138f5922010-12-07 20:46:14 +00001364 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001365}
1366
1367// atomic_compare_exchange_strong_explicit
1368
1369template <class _Tp>
1370inline _LIBCPP_INLINE_VISIBILITY
1371bool
1372atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1373 _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001374 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001375 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001376{
Howard Hinnant138f5922010-12-07 20:46:14 +00001377 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001378}
1379
1380template <class _Tp>
1381inline _LIBCPP_INLINE_VISIBILITY
1382bool
1383atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1384 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001385 memory_order __s, memory_order __f) _NOEXCEPT
Eric Fiselierb5ab51d2017-01-13 23:45:39 +00001386 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001387{
Howard Hinnant138f5922010-12-07 20:46:14 +00001388 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001389}
1390
Howard Hinnant138f5922010-12-07 20:46:14 +00001391// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001392
1393template <class _Tp>
Howard Hinnant138f5922010-12-07 20:46:14 +00001394inline _LIBCPP_INLINE_VISIBILITY
1395typename enable_if
1396<
1397 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1398 _Tp
1399>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001400atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001401{
Howard Hinnant138f5922010-12-07 20:46:14 +00001402 return __o->fetch_add(__op);
1403}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001404
Howard Hinnant138f5922010-12-07 20:46:14 +00001405template <class _Tp>
1406inline _LIBCPP_INLINE_VISIBILITY
1407typename enable_if
1408<
1409 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1410 _Tp
1411>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001412atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001413{
1414 return __o->fetch_add(__op);
1415}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001416
Howard Hinnant138f5922010-12-07 20:46:14 +00001417template <class _Tp>
1418inline _LIBCPP_INLINE_VISIBILITY
1419_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001420atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001421{
1422 return __o->fetch_add(__op);
1423}
1424
1425template <class _Tp>
1426inline _LIBCPP_INLINE_VISIBILITY
1427_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001428atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001429{
1430 return __o->fetch_add(__op);
1431}
1432
1433// atomic_fetch_add_explicit
1434
1435template <class _Tp>
1436inline _LIBCPP_INLINE_VISIBILITY
1437typename enable_if
1438<
1439 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1440 _Tp
1441>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001442atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001443{
1444 return __o->fetch_add(__op, __m);
1445}
1446
1447template <class _Tp>
1448inline _LIBCPP_INLINE_VISIBILITY
1449typename enable_if
1450<
1451 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1452 _Tp
1453>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001454atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001455{
1456 return __o->fetch_add(__op, __m);
1457}
1458
1459template <class _Tp>
1460inline _LIBCPP_INLINE_VISIBILITY
1461_Tp*
1462atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001463 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001464{
1465 return __o->fetch_add(__op, __m);
1466}
1467
1468template <class _Tp>
1469inline _LIBCPP_INLINE_VISIBILITY
1470_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001471atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001472{
1473 return __o->fetch_add(__op, __m);
1474}
1475
1476// atomic_fetch_sub
1477
1478template <class _Tp>
1479inline _LIBCPP_INLINE_VISIBILITY
1480typename enable_if
1481<
1482 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1483 _Tp
1484>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001485atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001486{
1487 return __o->fetch_sub(__op);
1488}
1489
1490template <class _Tp>
1491inline _LIBCPP_INLINE_VISIBILITY
1492typename enable_if
1493<
1494 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1495 _Tp
1496>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001497atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001498{
1499 return __o->fetch_sub(__op);
1500}
1501
1502template <class _Tp>
1503inline _LIBCPP_INLINE_VISIBILITY
1504_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001505atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001506{
1507 return __o->fetch_sub(__op);
1508}
1509
1510template <class _Tp>
1511inline _LIBCPP_INLINE_VISIBILITY
1512_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001513atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001514{
1515 return __o->fetch_sub(__op);
1516}
1517
1518// atomic_fetch_sub_explicit
1519
1520template <class _Tp>
1521inline _LIBCPP_INLINE_VISIBILITY
1522typename enable_if
1523<
1524 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1525 _Tp
1526>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001527atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001528{
1529 return __o->fetch_sub(__op, __m);
1530}
1531
1532template <class _Tp>
1533inline _LIBCPP_INLINE_VISIBILITY
1534typename enable_if
1535<
1536 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1537 _Tp
1538>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001539atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001540{
1541 return __o->fetch_sub(__op, __m);
1542}
1543
1544template <class _Tp>
1545inline _LIBCPP_INLINE_VISIBILITY
1546_Tp*
1547atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001548 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001549{
1550 return __o->fetch_sub(__op, __m);
1551}
1552
1553template <class _Tp>
1554inline _LIBCPP_INLINE_VISIBILITY
1555_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001556atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001557{
1558 return __o->fetch_sub(__op, __m);
1559}
1560
1561// atomic_fetch_and
1562
1563template <class _Tp>
1564inline _LIBCPP_INLINE_VISIBILITY
1565typename enable_if
1566<
1567 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1568 _Tp
1569>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001570atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001571{
1572 return __o->fetch_and(__op);
1573}
1574
1575template <class _Tp>
1576inline _LIBCPP_INLINE_VISIBILITY
1577typename enable_if
1578<
1579 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1580 _Tp
1581>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001582atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001583{
1584 return __o->fetch_and(__op);
1585}
1586
1587// atomic_fetch_and_explicit
1588
1589template <class _Tp>
1590inline _LIBCPP_INLINE_VISIBILITY
1591typename enable_if
1592<
1593 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1594 _Tp
1595>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001596atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001597{
1598 return __o->fetch_and(__op, __m);
1599}
1600
1601template <class _Tp>
1602inline _LIBCPP_INLINE_VISIBILITY
1603typename enable_if
1604<
1605 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1606 _Tp
1607>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001608atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001609{
1610 return __o->fetch_and(__op, __m);
1611}
1612
1613// atomic_fetch_or
1614
1615template <class _Tp>
1616inline _LIBCPP_INLINE_VISIBILITY
1617typename enable_if
1618<
1619 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1620 _Tp
1621>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001622atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001623{
1624 return __o->fetch_or(__op);
1625}
1626
1627template <class _Tp>
1628inline _LIBCPP_INLINE_VISIBILITY
1629typename enable_if
1630<
1631 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1632 _Tp
1633>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001634atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001635{
1636 return __o->fetch_or(__op);
1637}
1638
1639// atomic_fetch_or_explicit
1640
1641template <class _Tp>
1642inline _LIBCPP_INLINE_VISIBILITY
1643typename enable_if
1644<
1645 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1646 _Tp
1647>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001648atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001649{
1650 return __o->fetch_or(__op, __m);
1651}
1652
1653template <class _Tp>
1654inline _LIBCPP_INLINE_VISIBILITY
1655typename enable_if
1656<
1657 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1658 _Tp
1659>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001660atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001661{
1662 return __o->fetch_or(__op, __m);
1663}
1664
1665// atomic_fetch_xor
1666
1667template <class _Tp>
1668inline _LIBCPP_INLINE_VISIBILITY
1669typename enable_if
1670<
1671 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1672 _Tp
1673>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001674atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001675{
1676 return __o->fetch_xor(__op);
1677}
1678
1679template <class _Tp>
1680inline _LIBCPP_INLINE_VISIBILITY
1681typename enable_if
1682<
1683 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1684 _Tp
1685>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001686atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001687{
1688 return __o->fetch_xor(__op);
1689}
1690
1691// atomic_fetch_xor_explicit
1692
1693template <class _Tp>
1694inline _LIBCPP_INLINE_VISIBILITY
1695typename enable_if
1696<
1697 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1698 _Tp
1699>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001700atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001701{
1702 return __o->fetch_xor(__op, __m);
1703}
1704
1705template <class _Tp>
1706inline _LIBCPP_INLINE_VISIBILITY
1707typename enable_if
1708<
1709 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1710 _Tp
1711>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001712atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001713{
1714 return __o->fetch_xor(__op, __m);
1715}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001716
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001717// flag type and operations
1718
1719typedef struct atomic_flag
1720{
David Chisnall26ed3f42011-12-19 11:44:20 +00001721 _Atomic(bool) __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001722
1723 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001724 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001725 {return __c11_atomic_exchange(&__a_, true, __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001726 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001727 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001728 {return __c11_atomic_exchange(&__a_, true, __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001729 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001730 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001731 {__c11_atomic_store(&__a_, false, __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001732 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001733 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001734 {__c11_atomic_store(&__a_, false, __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001735
1736 _LIBCPP_INLINE_VISIBILITY
Eric Fiselier07b2b552016-11-18 06:42:17 +00001737#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant3d284222013-05-02 20:18:43 +00001738 atomic_flag() _NOEXCEPT = default;
1739#else
1740 atomic_flag() _NOEXCEPT : __a_() {}
Eric Fiselier07b2b552016-11-18 06:42:17 +00001741#endif // _LIBCPP_CXX03_LANG
Howard Hinnant3d284222013-05-02 20:18:43 +00001742
Marshall Clowcf990752018-04-25 14:27:29 +00001743 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
Eric Fiselierfec26a92016-05-03 02:12:26 +00001744 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001745
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001746#ifndef _LIBCPP_CXX03_LANG
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001747 atomic_flag(const atomic_flag&) = delete;
1748 atomic_flag& operator=(const atomic_flag&) = delete;
1749 atomic_flag& operator=(const atomic_flag&) volatile = delete;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001750#else
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001751private:
1752 atomic_flag(const atomic_flag&);
1753 atomic_flag& operator=(const atomic_flag&);
1754 atomic_flag& operator=(const atomic_flag&) volatile;
Eric Fiselier2d8515f2017-01-06 20:58:25 +00001755#endif
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001756} atomic_flag;
1757
1758inline _LIBCPP_INLINE_VISIBILITY
1759bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001760atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001761{
1762 return __o->test_and_set();
1763}
1764
1765inline _LIBCPP_INLINE_VISIBILITY
1766bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001767atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001768{
1769 return __o->test_and_set();
1770}
1771
1772inline _LIBCPP_INLINE_VISIBILITY
1773bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001774atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001775{
1776 return __o->test_and_set(__m);
1777}
1778
1779inline _LIBCPP_INLINE_VISIBILITY
1780bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001781atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001782{
1783 return __o->test_and_set(__m);
1784}
1785
1786inline _LIBCPP_INLINE_VISIBILITY
1787void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001788atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001789{
1790 __o->clear();
1791}
1792
1793inline _LIBCPP_INLINE_VISIBILITY
1794void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001795atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001796{
1797 __o->clear();
1798}
1799
1800inline _LIBCPP_INLINE_VISIBILITY
1801void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001802atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001803{
1804 __o->clear(__m);
1805}
1806
1807inline _LIBCPP_INLINE_VISIBILITY
1808void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001809atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001810{
1811 __o->clear(__m);
1812}
1813
1814// fences
1815
1816inline _LIBCPP_INLINE_VISIBILITY
1817void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001818atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001819{
Richard Smith27a4a972012-04-11 18:55:46 +00001820 __c11_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001821}
1822
1823inline _LIBCPP_INLINE_VISIBILITY
1824void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001825atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001826{
Richard Smith27a4a972012-04-11 18:55:46 +00001827 __c11_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001828}
1829
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001830// Atomics for standard typedef types
1831
Howard Hinnantf0af8d92013-01-04 18:58:50 +00001832typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001833typedef atomic<char> atomic_char;
1834typedef atomic<signed char> atomic_schar;
1835typedef atomic<unsigned char> atomic_uchar;
1836typedef atomic<short> atomic_short;
1837typedef atomic<unsigned short> atomic_ushort;
1838typedef atomic<int> atomic_int;
1839typedef atomic<unsigned int> atomic_uint;
1840typedef atomic<long> atomic_long;
1841typedef atomic<unsigned long> atomic_ulong;
1842typedef atomic<long long> atomic_llong;
1843typedef atomic<unsigned long long> atomic_ullong;
1844typedef atomic<char16_t> atomic_char16_t;
1845typedef atomic<char32_t> atomic_char32_t;
1846typedef atomic<wchar_t> atomic_wchar_t;
1847
1848typedef atomic<int_least8_t> atomic_int_least8_t;
1849typedef atomic<uint_least8_t> atomic_uint_least8_t;
1850typedef atomic<int_least16_t> atomic_int_least16_t;
1851typedef atomic<uint_least16_t> atomic_uint_least16_t;
1852typedef atomic<int_least32_t> atomic_int_least32_t;
1853typedef atomic<uint_least32_t> atomic_uint_least32_t;
1854typedef atomic<int_least64_t> atomic_int_least64_t;
1855typedef atomic<uint_least64_t> atomic_uint_least64_t;
1856
1857typedef atomic<int_fast8_t> atomic_int_fast8_t;
1858typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
1859typedef atomic<int_fast16_t> atomic_int_fast16_t;
1860typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1861typedef atomic<int_fast32_t> atomic_int_fast32_t;
1862typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1863typedef atomic<int_fast64_t> atomic_int_fast64_t;
1864typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1865
Marshall Clowf710afc2016-06-30 15:28:38 +00001866typedef atomic< int8_t> atomic_int8_t;
1867typedef atomic<uint8_t> atomic_uint8_t;
1868typedef atomic< int16_t> atomic_int16_t;
1869typedef atomic<uint16_t> atomic_uint16_t;
1870typedef atomic< int32_t> atomic_int32_t;
1871typedef atomic<uint32_t> atomic_uint32_t;
1872typedef atomic< int64_t> atomic_int64_t;
1873typedef atomic<uint64_t> atomic_uint64_t;
1874
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001875typedef atomic<intptr_t> atomic_intptr_t;
1876typedef atomic<uintptr_t> atomic_uintptr_t;
1877typedef atomic<size_t> atomic_size_t;
1878typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1879typedef atomic<intmax_t> atomic_intmax_t;
1880typedef atomic<uintmax_t> atomic_uintmax_t;
1881
Howard Hinnantf1f066a2010-09-29 21:20:03 +00001882#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00001883#define ATOMIC_VAR_INIT(__v) {__v}
1884
Howard Hinnant71be7292010-09-27 21:17:38 +00001885_LIBCPP_END_NAMESPACE_STD
1886
Howard Hinnant71be7292010-09-27 21:17:38 +00001887#endif // _LIBCPP_ATOMIC