blob: 91f18292d7360ee463b1cc20e87343e6c769b976 [file] [log] [blame]
Howard Hinnant71be7292010-09-27 21:17:38 +00001// -*- C++ -*-
2//===--------------------------- atomic -----------------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_ATOMIC
12#define _LIBCPP_ATOMIC
13
14/*
15 atomic synopsis
16
17namespace std
18{
19
20// order and consistency
21
22typedef enum memory_order
23{
Howard Hinnantdca6e712010-09-28 17:13:38 +000024 memory_order_relaxed,
25 memory_order_consume, // load-consume
26 memory_order_acquire, // load-acquire
27 memory_order_release, // store-release
28 memory_order_acq_rel, // store-release load-acquire
29 memory_order_seq_cst // store-release load-acquire
Howard Hinnant71be7292010-09-27 21:17:38 +000030} memory_order;
31
Howard Hinnanteee2c142012-04-11 20:14:21 +000032template <class T> T kill_dependency(T y) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000033
34// lock-free property
35
Howard Hinnant931e3402013-01-21 20:39:41 +000036#define ATOMIC_BOOL_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000037#define ATOMIC_CHAR_LOCK_FREE unspecified
38#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
39#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
40#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
41#define ATOMIC_SHORT_LOCK_FREE unspecified
42#define ATOMIC_INT_LOCK_FREE unspecified
43#define ATOMIC_LONG_LOCK_FREE unspecified
44#define ATOMIC_LLONG_LOCK_FREE unspecified
Howard Hinnant931e3402013-01-21 20:39:41 +000045#define ATOMIC_POINTER_LOCK_FREE unspecified
Howard Hinnant71be7292010-09-27 21:17:38 +000046
Howard Hinnant71be7292010-09-27 21:17:38 +000047// flag type and operations
48
49typedef struct atomic_flag
50{
Howard Hinnanteee2c142012-04-11 20:14:21 +000051 bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
52 bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
53 void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
54 void clear(memory_order m = memory_order_seq_cst) noexcept;
55 atomic_flag() noexcept = default;
Howard Hinnant71be7292010-09-27 21:17:38 +000056 atomic_flag(const atomic_flag&) = delete;
57 atomic_flag& operator=(const atomic_flag&) = delete;
58 atomic_flag& operator=(const atomic_flag&) volatile = delete;
59} atomic_flag;
60
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000061bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000062 atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000063
64bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000065 atomic_flag_test_and_set(atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000066
67bool
68 atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
Howard Hinnanteee2c142012-04-11 20:14:21 +000069 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000070
71bool
Howard Hinnanteee2c142012-04-11 20:14:21 +000072 atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000073
74void
Howard Hinnanteee2c142012-04-11 20:14:21 +000075 atomic_flag_clear(volatile atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000076
77void
Howard Hinnanteee2c142012-04-11 20:14:21 +000078 atomic_flag_clear(atomic_flag* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000079
80void
Howard Hinnanteee2c142012-04-11 20:14:21 +000081 atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +000082
83void
Howard Hinnanteee2c142012-04-11 20:14:21 +000084 atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +000085
86#define ATOMIC_FLAG_INIT see below
Howard Hinnant493d1d92010-10-19 16:51:18 +000087#define ATOMIC_VAR_INIT(value) see below
Howard Hinnant71be7292010-09-27 21:17:38 +000088
Howard Hinnant71be7292010-09-27 21:17:38 +000089template <class T>
90struct atomic
91{
Howard Hinnanteee2c142012-04-11 20:14:21 +000092 bool is_lock_free() const volatile noexcept;
93 bool is_lock_free() const noexcept;
94 void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
95 void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
96 T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
97 T load(memory_order m = memory_order_seq_cst) const noexcept;
98 operator T() const volatile noexcept;
99 operator T() const noexcept;
100 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
101 T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000102 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000103 memory_order s, memory_order f) volatile noexcept;
104 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000105 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000106 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000107 bool compare_exchange_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000108 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000109 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000110 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000111 bool compare_exchange_weak(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000112 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000113 bool compare_exchange_strong(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_strong(T& expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000116 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000117
Howard Hinnanteee2c142012-04-11 20:14:21 +0000118 atomic() noexcept = default;
119 constexpr atomic(T desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000120 atomic(const atomic&) = delete;
121 atomic& operator=(const atomic&) = delete;
122 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000123 T operator=(T) volatile noexcept;
124 T operator=(T) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000125};
126
127template <>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000128struct atomic<integral>
Howard Hinnant71be7292010-09-27 21:17:38 +0000129{
Howard Hinnanteee2c142012-04-11 20:14:21 +0000130 bool is_lock_free() const volatile noexcept;
131 bool is_lock_free() const noexcept;
132 void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
133 void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
134 integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
135 integral load(memory_order m = memory_order_seq_cst) const noexcept;
136 operator integral() const volatile noexcept;
137 operator integral() const noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000138 integral exchange(integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000139 memory_order m = memory_order_seq_cst) volatile noexcept;
140 integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000141 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000142 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000143 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000144 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000145 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000146 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000147 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000148 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000149 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000150 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000151 bool compare_exchange_weak(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000152 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000153 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000154 memory_order m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000155 bool compare_exchange_strong(integral& expc, integral desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000156 memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000157
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000158 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000159 fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
160 integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000161 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000162 fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
163 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000164 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000165 fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
166 integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000167 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000168 fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
169 integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000170 integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000171 fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
172 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000173
Howard Hinnanteee2c142012-04-11 20:14:21 +0000174 atomic() noexcept = default;
175 constexpr atomic(integral desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000176 atomic(const atomic&) = delete;
177 atomic& operator=(const atomic&) = delete;
178 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnanteee2c142012-04-11 20:14:21 +0000179 integral operator=(integral desr) volatile noexcept;
180 integral operator=(integral desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000181
Howard Hinnanteee2c142012-04-11 20:14:21 +0000182 integral operator++(int) volatile noexcept;
183 integral operator++(int) noexcept;
184 integral operator--(int) volatile noexcept;
185 integral operator--(int) noexcept;
186 integral operator++() volatile noexcept;
187 integral operator++() noexcept;
188 integral operator--() volatile noexcept;
189 integral operator--() noexcept;
190 integral operator+=(integral op) volatile noexcept;
191 integral operator+=(integral op) noexcept;
192 integral operator-=(integral op) volatile noexcept;
193 integral operator-=(integral op) noexcept;
194 integral operator&=(integral op) volatile noexcept;
195 integral operator&=(integral op) noexcept;
196 integral operator|=(integral op) volatile noexcept;
197 integral operator|=(integral op) noexcept;
198 integral operator^=(integral op) volatile noexcept;
199 integral operator^=(integral op) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000200};
201
202template <class T>
203struct atomic<T*>
Howard Hinnant71be7292010-09-27 21:17:38 +0000204{
Howard Hinnanteee2c142012-04-11 20:14:21 +0000205 bool is_lock_free() const volatile noexcept;
206 bool is_lock_free() const noexcept;
207 void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
208 void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
209 T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
210 T* load(memory_order m = memory_order_seq_cst) const noexcept;
211 operator T*() const volatile noexcept;
212 operator T*() const noexcept;
213 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
214 T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000215 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000216 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000217 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000218 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000219 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000220 memory_order s, memory_order f) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000221 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000222 memory_order s, memory_order f) 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 m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000225 bool compare_exchange_weak(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000226 memory_order m = memory_order_seq_cst) 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 m = memory_order_seq_cst) volatile noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000229 bool compare_exchange_strong(T*& expc, T* desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000230 memory_order m = memory_order_seq_cst) noexcept;
231 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
232 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
233 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
234 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000235
Howard Hinnanteee2c142012-04-11 20:14:21 +0000236 atomic() noexcept = default;
237 constexpr atomic(T* desr) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000238 atomic(const atomic&) = delete;
239 atomic& operator=(const atomic&) = delete;
240 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000241
Howard Hinnanteee2c142012-04-11 20:14:21 +0000242 T* operator=(T*) volatile noexcept;
243 T* operator=(T*) noexcept;
244 T* operator++(int) volatile noexcept;
245 T* operator++(int) noexcept;
246 T* operator--(int) volatile noexcept;
247 T* operator--(int) noexcept;
248 T* operator++() volatile noexcept;
249 T* operator++() noexcept;
250 T* operator--() volatile noexcept;
251 T* operator--() noexcept;
252 T* operator+=(ptrdiff_t op) volatile noexcept;
253 T* operator+=(ptrdiff_t op) noexcept;
254 T* operator-=(ptrdiff_t op) volatile noexcept;
255 T* operator-=(ptrdiff_t op) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000256};
257
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000258
259template <class T>
260 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000261 atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000262
263template <class T>
264 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000265 atomic_is_lock_free(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000266
267template <class T>
268 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000269 atomic_init(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000270
271template <class T>
272 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000273 atomic_init(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000274
275template <class T>
276 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000277 atomic_store(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000278
279template <class T>
280 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000281 atomic_store(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000282
283template <class T>
284 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000285 atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000286
287template <class T>
288 void
Howard Hinnanteee2c142012-04-11 20:14:21 +0000289 atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000290
291template <class T>
292 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000293 atomic_load(const volatile atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000294
295template <class T>
296 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000297 atomic_load(const atomic<T>* obj) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000298
299template <class T>
300 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000301 atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000302
303template <class T>
304 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000305 atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000306
307template <class T>
308 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000309 atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000310
311template <class T>
312 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000313 atomic_exchange(atomic<T>* obj, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000314
315template <class T>
316 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000317 atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000318
319template <class T>
320 T
Howard Hinnanteee2c142012-04-11 20:14:21 +0000321 atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000322
323template <class T>
324 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000325 atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000326
327template <class T>
328 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000329 atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000330
331template <class T>
332 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000333 atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000334
335template <class T>
336 bool
Howard Hinnanteee2c142012-04-11 20:14:21 +0000337 atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000338
339template <class T>
340 bool
341 atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
342 T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000343 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000344
345template <class T>
346 bool
347 atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000348 memory_order s, memory_order f) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000349
350template <class T>
351 bool
352 atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
353 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(atomic<T>* obj, T* expc,
359 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 Integral>
363 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000364 atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000365
366template <class Integral>
367 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000368 atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000369
370template <class Integral>
371 Integral
372 atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000373 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000374template <class Integral>
375 Integral
376 atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000377 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000378template <class Integral>
379 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000380 atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000381
382template <class Integral>
383 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000384 atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000385
386template <class Integral>
387 Integral
388 atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000389 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000390template <class Integral>
391 Integral
392 atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000393 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000394template <class Integral>
395 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000396 atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000397
398template <class Integral>
399 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000400 atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000401
402template <class Integral>
403 Integral
404 atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000405 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000406template <class Integral>
407 Integral
408 atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000409 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000410template <class Integral>
411 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000412 atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000413
414template <class Integral>
415 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000416 atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000417
418template <class Integral>
419 Integral
420 atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000421 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000422template <class Integral>
423 Integral
424 atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000425 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000426template <class Integral>
427 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000428 atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000429
430template <class Integral>
431 Integral
Howard Hinnanteee2c142012-04-11 20:14:21 +0000432 atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000433
434template <class Integral>
435 Integral
436 atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000437 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000438template <class Integral>
439 Integral
440 atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000441 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000442
443template <class T>
444 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000445 atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000446
447template <class T>
448 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000449 atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000450
451template <class T>
452 T*
453 atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000454 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000455template <class T>
456 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000457 atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000458
459template <class T>
460 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000461 atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000462
463template <class T>
464 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000465 atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000466
467template <class T>
468 T*
469 atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000470 memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000471template <class T>
472 T*
Howard Hinnanteee2c142012-04-11 20:14:21 +0000473 atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000474
475// Atomics for standard typedef types
476
Howard Hinnantf0af8d92013-01-04 18:58:50 +0000477typedef atomic<bool> atomic_bool;
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000478typedef atomic<char> atomic_char;
479typedef atomic<signed char> atomic_schar;
480typedef atomic<unsigned char> atomic_uchar;
481typedef atomic<short> atomic_short;
482typedef atomic<unsigned short> atomic_ushort;
483typedef atomic<int> atomic_int;
484typedef atomic<unsigned int> atomic_uint;
485typedef atomic<long> atomic_long;
486typedef atomic<unsigned long> atomic_ulong;
487typedef atomic<long long> atomic_llong;
488typedef atomic<unsigned long long> atomic_ullong;
489typedef atomic<char16_t> atomic_char16_t;
490typedef atomic<char32_t> atomic_char32_t;
491typedef atomic<wchar_t> atomic_wchar_t;
492
493typedef atomic<int_least8_t> atomic_int_least8_t;
494typedef atomic<uint_least8_t> atomic_uint_least8_t;
495typedef atomic<int_least16_t> atomic_int_least16_t;
496typedef atomic<uint_least16_t> atomic_uint_least16_t;
497typedef atomic<int_least32_t> atomic_int_least32_t;
498typedef atomic<uint_least32_t> atomic_uint_least32_t;
499typedef atomic<int_least64_t> atomic_int_least64_t;
500typedef atomic<uint_least64_t> atomic_uint_least64_t;
501
502typedef atomic<int_fast8_t> atomic_int_fast8_t;
503typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
504typedef atomic<int_fast16_t> atomic_int_fast16_t;
505typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
506typedef atomic<int_fast32_t> atomic_int_fast32_t;
507typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
508typedef atomic<int_fast64_t> atomic_int_fast64_t;
509typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
510
511typedef atomic<intptr_t> atomic_intptr_t;
512typedef atomic<uintptr_t> atomic_uintptr_t;
513typedef atomic<size_t> atomic_size_t;
514typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
515typedef atomic<intmax_t> atomic_intmax_t;
516typedef atomic<uintmax_t> atomic_uintmax_t;
517
Howard Hinnant71be7292010-09-27 21:17:38 +0000518// fences
519
Howard Hinnanteee2c142012-04-11 20:14:21 +0000520void atomic_thread_fence(memory_order m) noexcept;
521void atomic_signal_fence(memory_order m) noexcept;
Howard Hinnant71be7292010-09-27 21:17:38 +0000522
523} // std
524
525*/
526
527#include <__config>
Howard Hinnant7bfaeb82010-12-06 23:10:08 +0000528#include <cstddef>
529#include <cstdint>
530#include <type_traits>
Howard Hinnant71be7292010-09-27 21:17:38 +0000531
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000532#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnant71be7292010-09-27 21:17:38 +0000533#pragma GCC system_header
Howard Hinnantaaaa52b2011-10-17 20:05:10 +0000534#endif
Howard Hinnant71be7292010-09-27 21:17:38 +0000535
536_LIBCPP_BEGIN_NAMESPACE_STD
537
Dan Albert7b65ace2014-08-09 23:51:51 +0000538#if !__has_feature(cxx_atomic) && _GNUC_VER < 407
Howard Hinnant14fdaba2011-03-31 16:39:39 +0000539#error <atomic> is not implemented
540#else
541
Howard Hinnantdca6e712010-09-28 17:13:38 +0000542typedef enum memory_order
543{
544 memory_order_relaxed, memory_order_consume, memory_order_acquire,
545 memory_order_release, memory_order_acq_rel, memory_order_seq_cst
546} memory_order;
547
Dan Albert7b65ace2014-08-09 23:51:51 +0000548#if _GNUC_VER >= 407
549namespace __gcc_atomic {
550template <typename T>
551struct __gcc_atomic_t {
552 __gcc_atomic_t() _NOEXCEPT {}
553 explicit __gcc_atomic_t(T value) _NOEXCEPT : __a_value(value) {}
554 T __a_value;
555};
556#define _Atomic(x) __gcc_atomic::__gcc_atomic_t<x>
557
558template <typename T> T __create();
559
560template <typename __Tp, typename __Td>
561typename enable_if<sizeof(__Tp()->__a_value = __create<__Td>()), char>::type
562 __test_atomic_assignable(int);
563template <typename T, typename U>
564__two __test_atomic_assignable(...);
565
566template <typename __Tp, typename __Td>
567struct __can_assign {
568 static const bool value =
569 sizeof(__test_atomic_assignable<__Tp, __Td>(1)) == sizeof(char);
570};
571
572static inline constexpr int __to_gcc_order(memory_order __order) {
573 // Avoid switch statement to make this a constexpr.
574 return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
575 (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
576 (__order == memory_order_release ? __ATOMIC_RELEASE:
577 (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
578 (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
579 __ATOMIC_CONSUME))));
580}
581
582} // namespace __gcc_atomic
583
584template <typename _Tp>
585static inline
586typename enable_if<
587 __gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value>::type
588__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) {
589 __a->__a_value = __val;
590}
591
592template <typename _Tp>
593static inline
594typename enable_if<
595 !__gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value &&
596 __gcc_atomic::__can_assign< _Atomic(_Tp)*, _Tp>::value>::type
597__c11_atomic_init(volatile _Atomic(_Tp)* __a, _Tp __val) {
598 // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
599 // the default operator= in an object is not volatile, a byte-by-byte copy
600 // is required.
601 volatile char* to = reinterpret_cast<volatile char*>(&__a->__a_value);
602 volatile char* end = to + sizeof(_Tp);
603 char* from = reinterpret_cast<char*>(&__val);
604 while (to != end) {
605 *to++ = *from++;
606 }
607}
608
609template <typename _Tp>
610static inline void __c11_atomic_init(_Atomic(_Tp)* __a, _Tp __val) {
611 __a->__a_value = __val;
612}
613
614static inline void __c11_atomic_thread_fence(memory_order __order) {
615 __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order));
616}
617
618static inline void __c11_atomic_signal_fence(memory_order __order) {
619 __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order));
620}
621
622static inline bool __c11_atomic_is_lock_free(size_t __size) {
623 return __atomic_is_lock_free(__size, 0);
624}
625
626template <typename _Tp>
627static inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a, _Tp __val,
628 memory_order __order) {
629 return __atomic_store(&__a->__a_value, &__val,
630 __gcc_atomic::__to_gcc_order(__order));
631}
632
633template <typename _Tp>
634static inline void __c11_atomic_store(_Atomic(_Tp)* __a, _Tp __val,
635 memory_order __order) {
636 return __atomic_store(&__a->__a_value, &__val,
637 __gcc_atomic::__to_gcc_order(__order));
638}
639
640template <typename _Tp>
641static inline _Tp __c11_atomic_load(volatile _Atomic(_Tp)* __a,
642 memory_order __order) {
643 _Tp __ret;
644 __atomic_load(&__a->__a_value, &__ret,
645 __gcc_atomic::__to_gcc_order(__order));
646 return __ret;
647}
648
649template <typename _Tp>
650static inline _Tp __c11_atomic_load(_Atomic(_Tp)* __a, memory_order __order) {
651 _Tp __ret;
652 __atomic_load(&__a->__a_value, &__ret,
653 __gcc_atomic::__to_gcc_order(__order));
654 return __ret;
655}
656
657template <typename _Tp>
658static inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a,
659 _Tp __value, memory_order __order) {
660 _Tp __ret;
661 __atomic_exchange(&__a->__a_value, &__value, &__ret,
662 __gcc_atomic::__to_gcc_order(__order));
663 return __ret;
664}
665
666template <typename _Tp>
667static inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value,
668 memory_order __order) {
669 _Tp __ret;
670 __atomic_exchange(&__a->__a_value, &__value, &__ret,
671 __gcc_atomic::__to_gcc_order(__order));
672 return __ret;
673}
674
675template <typename _Tp>
676static inline bool __c11_atomic_compare_exchange_strong(
677 volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
678 memory_order __success, memory_order __failure) {
679 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
680 false,
681 __gcc_atomic::__to_gcc_order(__success),
682 __gcc_atomic::__to_gcc_order(__failure));
683}
684
685template <typename _Tp>
686static inline bool __c11_atomic_compare_exchange_strong(
687 _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
688 memory_order __failure) {
689 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
690 false,
691 __gcc_atomic::__to_gcc_order(__success),
692 __gcc_atomic::__to_gcc_order(__failure));
693}
694
695template <typename _Tp>
696static inline bool __c11_atomic_compare_exchange_weak(
697 volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
698 memory_order __success, memory_order __failure) {
699 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
700 true,
701 __gcc_atomic::__to_gcc_order(__success),
702 __gcc_atomic::__to_gcc_order(__failure));
703}
704
705template <typename _Tp>
706static inline bool __c11_atomic_compare_exchange_weak(
707 _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
708 memory_order __failure) {
709 return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
710 true,
711 __gcc_atomic::__to_gcc_order(__success),
712 __gcc_atomic::__to_gcc_order(__failure));
713}
714
715template <typename _Tp>
716struct __skip_amt { enum {value = 1}; };
717
718template <typename _Tp>
719struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
720
721// FIXME: Haven't figured out what the spec says about using arrays with
722// atomic_fetch_add. Force a failure rather than creating bad behavior.
723template <typename _Tp>
724struct __skip_amt<_Tp[]> { };
725template <typename _Tp, int n>
726struct __skip_amt<_Tp[n]> { };
727
728template <typename _Tp, typename _Td>
729static inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a,
730 _Td __delta, memory_order __order) {
731 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
732 __gcc_atomic::__to_gcc_order(__order));
733}
734
735template <typename _Tp, typename _Td>
736static inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta,
737 memory_order __order) {
738 return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
739 __gcc_atomic::__to_gcc_order(__order));
740}
741
742template <typename _Tp, typename _Td>
743static inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a,
744 _Td __delta, memory_order __order) {
745 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
746 __gcc_atomic::__to_gcc_order(__order));
747}
748
749template <typename _Tp, typename _Td>
750static inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta,
751 memory_order __order) {
752 return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
753 __gcc_atomic::__to_gcc_order(__order));
754}
755
756template <typename _Tp>
757static inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a,
758 _Tp __pattern, memory_order __order) {
759 return __atomic_fetch_and(&__a->__a_value, __pattern,
760 __gcc_atomic::__to_gcc_order(__order));
761}
762
763template <typename _Tp>
764static inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a,
765 _Tp __pattern, memory_order __order) {
766 return __atomic_fetch_and(&__a->__a_value, __pattern,
767 __gcc_atomic::__to_gcc_order(__order));
768}
769
770template <typename _Tp>
771static inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a,
772 _Tp __pattern, memory_order __order) {
773 return __atomic_fetch_or(&__a->__a_value, __pattern,
774 __gcc_atomic::__to_gcc_order(__order));
775}
776
777template <typename _Tp>
778static inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern,
779 memory_order __order) {
780 return __atomic_fetch_or(&__a->__a_value, __pattern,
781 __gcc_atomic::__to_gcc_order(__order));
782}
783
784template <typename _Tp>
785static inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a,
786 _Tp __pattern, memory_order __order) {
787 return __atomic_fetch_xor(&__a->__a_value, __pattern,
788 __gcc_atomic::__to_gcc_order(__order));
789}
790
791template <typename _Tp>
792static inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern,
793 memory_order __order) {
794 return __atomic_fetch_xor(&__a->__a_value, __pattern,
795 __gcc_atomic::__to_gcc_order(__order));
796}
797#endif // _GNUC_VER >= 407
798
Howard Hinnantdca6e712010-09-28 17:13:38 +0000799template <class _Tp>
800inline _LIBCPP_INLINE_VISIBILITY
801_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +0000802kill_dependency(_Tp __y) _NOEXCEPT
Howard Hinnantdca6e712010-09-28 17:13:38 +0000803{
804 return __y;
805}
Howard Hinnant71be7292010-09-27 21:17:38 +0000806
Howard Hinnant138f5922010-12-07 20:46:14 +0000807// general atomic<T>
808
809template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
810struct __atomic_base // false
811{
Howard Hinnantd5eebd62012-09-16 20:33:09 +0000812 mutable _Atomic(_Tp) __a_;
Howard Hinnant138f5922010-12-07 20:46:14 +0000813
814 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000815 bool is_lock_free() const volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000816 {return __c11_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +0000817 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000818 bool is_lock_free() const _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000819 {return __c11_atomic_is_lock_free(sizeof(_Tp));}
Howard Hinnant138f5922010-12-07 20:46:14 +0000820 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000821 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000822 {__c11_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000823 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000824 void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000825 {__c11_atomic_store(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000826 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000827 _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000828 {return __c11_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000829 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000830 _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000831 {return __c11_atomic_load(&__a_, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000832 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000833 operator _Tp() const volatile _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +0000834 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000835 operator _Tp() const _NOEXCEPT {return load();}
Howard Hinnant138f5922010-12-07 20:46:14 +0000836 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000837 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000838 {return __c11_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000839 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000840 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000841 {return __c11_atomic_exchange(&__a_, __d, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000842 _LIBCPP_INLINE_VISIBILITY
843 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000844 memory_order __s, memory_order __f) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000845 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000846 _LIBCPP_INLINE_VISIBILITY
847 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000848 memory_order __s, memory_order __f) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000849 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000850 _LIBCPP_INLINE_VISIBILITY
851 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000852 memory_order __s, memory_order __f) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000853 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000854 _LIBCPP_INLINE_VISIBILITY
855 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000856 memory_order __s, memory_order __f) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000857 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000858 _LIBCPP_INLINE_VISIBILITY
859 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000860 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000861 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000862 _LIBCPP_INLINE_VISIBILITY
863 bool compare_exchange_weak(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000864 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000865 {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000866 _LIBCPP_INLINE_VISIBILITY
867 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000868 memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000869 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000870 _LIBCPP_INLINE_VISIBILITY
871 bool compare_exchange_strong(_Tp& __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +0000872 memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000873 {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000874
875 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +0000876#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
877 __atomic_base() _NOEXCEPT = default;
878#else
879 __atomic_base() _NOEXCEPT : __a_() {}
880#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
881
Howard Hinnant138f5922010-12-07 20:46:14 +0000882 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000883 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
Howard Hinnant6ac60f82010-12-08 17:20:28 +0000884#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
Howard Hinnant138f5922010-12-07 20:46:14 +0000885 __atomic_base(const __atomic_base&) = delete;
886 __atomic_base& operator=(const __atomic_base&) = delete;
887 __atomic_base& operator=(const __atomic_base&) volatile = delete;
Howard Hinnant6ac60f82010-12-08 17:20:28 +0000888#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
889private:
890 __atomic_base(const __atomic_base&);
891 __atomic_base& operator=(const __atomic_base&);
892 __atomic_base& operator=(const __atomic_base&) volatile;
893#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
Howard Hinnant138f5922010-12-07 20:46:14 +0000894};
895
896// atomic<Integral>
897
898template <class _Tp>
899struct __atomic_base<_Tp, true>
900 : public __atomic_base<_Tp, false>
901{
902 typedef __atomic_base<_Tp, false> __base;
903 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +0000904 __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +0000905 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000906 _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +0000907
908 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000909 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000910 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000911 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000912 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000913 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000914 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000915 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000916 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000917 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000918 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000919 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000920 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000921 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000922 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000923 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000924 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000925 {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000926 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000927 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000928 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000929 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000930 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000931 {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000932 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000933 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000934 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000935 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000936 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +0000937 {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000938
939 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000940 _Tp operator++(int) volatile _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +0000941 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000942 _Tp operator++(int) _NOEXCEPT {return fetch_add(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +0000943 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000944 _Tp operator--(int) volatile _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +0000945 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000946 _Tp operator--(int) _NOEXCEPT {return fetch_sub(_Tp(1));}
Howard Hinnant138f5922010-12-07 20:46:14 +0000947 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000948 _Tp operator++() volatile _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000949 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000950 _Tp operator++() _NOEXCEPT {return fetch_add(_Tp(1)) + _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000951 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000952 _Tp operator--() volatile _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000953 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000954 _Tp operator--() _NOEXCEPT {return fetch_sub(_Tp(1)) - _Tp(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +0000955 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000956 _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000957 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000958 _Tp operator+=(_Tp __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000959 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000960 _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000961 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000962 _Tp operator-=(_Tp __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000963 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000964 _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000965 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000966 _Tp operator&=(_Tp __op) _NOEXCEPT {return fetch_and(__op) & __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000967 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000968 _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000969 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000970 _Tp operator|=(_Tp __op) _NOEXCEPT {return fetch_or(__op) | __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000971 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000972 _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000973 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000974 _Tp operator^=(_Tp __op) _NOEXCEPT {return fetch_xor(__op) ^ __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000975};
976
977// atomic<T>
978
979template <class _Tp>
980struct atomic
981 : public __atomic_base<_Tp>
982{
983 typedef __atomic_base<_Tp> __base;
984 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +0000985 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +0000986 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000987 _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant96e4cd62010-12-07 23:24:41 +0000988
989 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000990 _Tp operator=(_Tp __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +0000991 {__base::store(__d); return __d;}
992 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +0000993 _Tp operator=(_Tp __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +0000994 {__base::store(__d); return __d;}
Howard Hinnant138f5922010-12-07 20:46:14 +0000995};
996
997// atomic<T*>
998
999template <class _Tp>
1000struct atomic<_Tp*>
1001 : public __atomic_base<_Tp*>
1002{
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001003 typedef __atomic_base<_Tp*> __base;
Howard Hinnant138f5922010-12-07 20:46:14 +00001004 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001005 atomic() _NOEXCEPT _LIBCPP_DEFAULT
Howard Hinnant138f5922010-12-07 20:46:14 +00001006 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001007 _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
Howard Hinnant138f5922010-12-07 20:46:14 +00001008
1009 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001010 _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001011 {__base::store(__d); return __d;}
1012 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001013 _Tp* operator=(_Tp* __d) _NOEXCEPT
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001014 {__base::store(__d); return __d;}
1015
1016 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant138f5922010-12-07 20:46:14 +00001017 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001018 volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001019 {return __c11_atomic_fetch_add(&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_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001022 {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001023 _LIBCPP_INLINE_VISIBILITY
1024 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
Howard Hinnanteee2c142012-04-11 20:14:21 +00001025 volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001026 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001027 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001028 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001029 {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001030
1031 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001032 _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001033 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001034 _Tp* operator++(int) _NOEXCEPT {return fetch_add(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001035 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001036 _Tp* operator--(int) volatile _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001037 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001038 _Tp* operator--(int) _NOEXCEPT {return fetch_sub(1);}
Howard Hinnant138f5922010-12-07 20:46:14 +00001039 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001040 _Tp* operator++() volatile _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001041 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001042 _Tp* operator++() _NOEXCEPT {return fetch_add(1) + 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001043 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001044 _Tp* operator--() volatile _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001045 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001046 _Tp* operator--() _NOEXCEPT {return fetch_sub(1) - 1;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001047 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001048 _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001049 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001050 _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT {return fetch_add(__op) + __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001051 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001052 _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001053 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001054 _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT {return fetch_sub(__op) - __op;}
Howard Hinnant138f5922010-12-07 20:46:14 +00001055};
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001056
1057// atomic_is_lock_free
1058
1059template <class _Tp>
1060inline _LIBCPP_INLINE_VISIBILITY
1061bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001062atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001063{
Howard Hinnant138f5922010-12-07 20:46:14 +00001064 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001065}
1066
1067template <class _Tp>
1068inline _LIBCPP_INLINE_VISIBILITY
1069bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001070atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001071{
Howard Hinnant138f5922010-12-07 20:46:14 +00001072 return __o->is_lock_free();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001073}
1074
1075// atomic_init
1076
1077template <class _Tp>
1078inline _LIBCPP_INLINE_VISIBILITY
1079void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001080atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001081{
Richard Smith27a4a972012-04-11 18:55:46 +00001082 __c11_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001083}
1084
1085template <class _Tp>
1086inline _LIBCPP_INLINE_VISIBILITY
1087void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001088atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001089{
Richard Smith27a4a972012-04-11 18:55:46 +00001090 __c11_atomic_init(&__o->__a_, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001091}
1092
1093// atomic_store
1094
1095template <class _Tp>
1096inline _LIBCPP_INLINE_VISIBILITY
1097void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001098atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001099{
Howard Hinnant138f5922010-12-07 20:46:14 +00001100 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001101}
1102
1103template <class _Tp>
1104inline _LIBCPP_INLINE_VISIBILITY
1105void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001106atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001107{
Howard Hinnant138f5922010-12-07 20:46:14 +00001108 __o->store(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001109}
1110
1111// atomic_store_explicit
1112
1113template <class _Tp>
1114inline _LIBCPP_INLINE_VISIBILITY
1115void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001116atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001117{
Howard Hinnant138f5922010-12-07 20:46:14 +00001118 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001119}
1120
1121template <class _Tp>
1122inline _LIBCPP_INLINE_VISIBILITY
1123void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001124atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001125{
Howard Hinnant138f5922010-12-07 20:46:14 +00001126 __o->store(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001127}
1128
1129// atomic_load
1130
1131template <class _Tp>
1132inline _LIBCPP_INLINE_VISIBILITY
1133_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001134atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001135{
Howard Hinnant138f5922010-12-07 20:46:14 +00001136 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001137}
1138
1139template <class _Tp>
1140inline _LIBCPP_INLINE_VISIBILITY
1141_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001142atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001143{
Howard Hinnant138f5922010-12-07 20:46:14 +00001144 return __o->load();
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001145}
1146
1147// atomic_load_explicit
1148
1149template <class _Tp>
1150inline _LIBCPP_INLINE_VISIBILITY
1151_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001152atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001153{
Howard Hinnant138f5922010-12-07 20:46:14 +00001154 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001155}
1156
1157template <class _Tp>
1158inline _LIBCPP_INLINE_VISIBILITY
1159_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001160atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001161{
Howard Hinnant138f5922010-12-07 20:46:14 +00001162 return __o->load(__m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001163}
1164
1165// atomic_exchange
1166
1167template <class _Tp>
1168inline _LIBCPP_INLINE_VISIBILITY
1169_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001170atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001171{
Howard Hinnant138f5922010-12-07 20:46:14 +00001172 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001173}
1174
1175template <class _Tp>
1176inline _LIBCPP_INLINE_VISIBILITY
1177_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001178atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001179{
Howard Hinnant138f5922010-12-07 20:46:14 +00001180 return __o->exchange(__d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001181}
1182
1183// atomic_exchange_explicit
1184
1185template <class _Tp>
1186inline _LIBCPP_INLINE_VISIBILITY
1187_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001188atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001189{
Howard Hinnant138f5922010-12-07 20:46:14 +00001190 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001191}
1192
1193template <class _Tp>
1194inline _LIBCPP_INLINE_VISIBILITY
1195_Tp
Howard Hinnanteee2c142012-04-11 20:14:21 +00001196atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001197{
Howard Hinnant138f5922010-12-07 20:46:14 +00001198 return __o->exchange(__d, __m);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001199}
1200
1201// atomic_compare_exchange_weak
1202
1203template <class _Tp>
1204inline _LIBCPP_INLINE_VISIBILITY
1205bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001206atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001207{
Howard Hinnant138f5922010-12-07 20:46:14 +00001208 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001209}
1210
1211template <class _Tp>
1212inline _LIBCPP_INLINE_VISIBILITY
1213bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001214atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001215{
Howard Hinnant138f5922010-12-07 20:46:14 +00001216 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001217}
1218
1219// atomic_compare_exchange_strong
1220
1221template <class _Tp>
1222inline _LIBCPP_INLINE_VISIBILITY
1223bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001224atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001225{
Howard Hinnant138f5922010-12-07 20:46:14 +00001226 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001227}
1228
1229template <class _Tp>
1230inline _LIBCPP_INLINE_VISIBILITY
1231bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001232atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001233{
Howard Hinnant138f5922010-12-07 20:46:14 +00001234 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001235}
1236
1237// atomic_compare_exchange_weak_explicit
1238
1239template <class _Tp>
1240inline _LIBCPP_INLINE_VISIBILITY
1241bool
1242atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
1243 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001244 memory_order __s, memory_order __f) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001245{
Howard Hinnant138f5922010-12-07 20:46:14 +00001246 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001247}
1248
1249template <class _Tp>
1250inline _LIBCPP_INLINE_VISIBILITY
1251bool
1252atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001253 memory_order __s, memory_order __f) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001254{
Howard Hinnant138f5922010-12-07 20:46:14 +00001255 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001256}
1257
1258// atomic_compare_exchange_strong_explicit
1259
1260template <class _Tp>
1261inline _LIBCPP_INLINE_VISIBILITY
1262bool
1263atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1264 _Tp* __e, _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001265 memory_order __s, memory_order __f) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001266{
Howard Hinnant138f5922010-12-07 20:46:14 +00001267 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001268}
1269
1270template <class _Tp>
1271inline _LIBCPP_INLINE_VISIBILITY
1272bool
1273atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1274 _Tp __d,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001275 memory_order __s, memory_order __f) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001276{
Howard Hinnant138f5922010-12-07 20:46:14 +00001277 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001278}
1279
Howard Hinnant138f5922010-12-07 20:46:14 +00001280// atomic_fetch_add
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001281
1282template <class _Tp>
Howard Hinnant138f5922010-12-07 20:46:14 +00001283inline _LIBCPP_INLINE_VISIBILITY
1284typename enable_if
1285<
1286 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1287 _Tp
1288>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001289atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001290{
Howard Hinnant138f5922010-12-07 20:46:14 +00001291 return __o->fetch_add(__op);
1292}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001293
Howard Hinnant138f5922010-12-07 20:46:14 +00001294template <class _Tp>
1295inline _LIBCPP_INLINE_VISIBILITY
1296typename enable_if
1297<
1298 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1299 _Tp
1300>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001301atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001302{
1303 return __o->fetch_add(__op);
1304}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001305
Howard Hinnant138f5922010-12-07 20:46:14 +00001306template <class _Tp>
1307inline _LIBCPP_INLINE_VISIBILITY
1308_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001309atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001310{
1311 return __o->fetch_add(__op);
1312}
1313
1314template <class _Tp>
1315inline _LIBCPP_INLINE_VISIBILITY
1316_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001317atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001318{
1319 return __o->fetch_add(__op);
1320}
1321
1322// atomic_fetch_add_explicit
1323
1324template <class _Tp>
1325inline _LIBCPP_INLINE_VISIBILITY
1326typename enable_if
1327<
1328 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1329 _Tp
1330>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001331atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001332{
1333 return __o->fetch_add(__op, __m);
1334}
1335
1336template <class _Tp>
1337inline _LIBCPP_INLINE_VISIBILITY
1338typename enable_if
1339<
1340 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1341 _Tp
1342>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001343atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001344{
1345 return __o->fetch_add(__op, __m);
1346}
1347
1348template <class _Tp>
1349inline _LIBCPP_INLINE_VISIBILITY
1350_Tp*
1351atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001352 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001353{
1354 return __o->fetch_add(__op, __m);
1355}
1356
1357template <class _Tp>
1358inline _LIBCPP_INLINE_VISIBILITY
1359_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001360atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001361{
1362 return __o->fetch_add(__op, __m);
1363}
1364
1365// atomic_fetch_sub
1366
1367template <class _Tp>
1368inline _LIBCPP_INLINE_VISIBILITY
1369typename enable_if
1370<
1371 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1372 _Tp
1373>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001374atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001375{
1376 return __o->fetch_sub(__op);
1377}
1378
1379template <class _Tp>
1380inline _LIBCPP_INLINE_VISIBILITY
1381typename enable_if
1382<
1383 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1384 _Tp
1385>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001386atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001387{
1388 return __o->fetch_sub(__op);
1389}
1390
1391template <class _Tp>
1392inline _LIBCPP_INLINE_VISIBILITY
1393_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001394atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001395{
1396 return __o->fetch_sub(__op);
1397}
1398
1399template <class _Tp>
1400inline _LIBCPP_INLINE_VISIBILITY
1401_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001402atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001403{
1404 return __o->fetch_sub(__op);
1405}
1406
1407// atomic_fetch_sub_explicit
1408
1409template <class _Tp>
1410inline _LIBCPP_INLINE_VISIBILITY
1411typename enable_if
1412<
1413 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1414 _Tp
1415>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001416atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001417{
1418 return __o->fetch_sub(__op, __m);
1419}
1420
1421template <class _Tp>
1422inline _LIBCPP_INLINE_VISIBILITY
1423typename enable_if
1424<
1425 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1426 _Tp
1427>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001428atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001429{
1430 return __o->fetch_sub(__op, __m);
1431}
1432
1433template <class _Tp>
1434inline _LIBCPP_INLINE_VISIBILITY
1435_Tp*
1436atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
Howard Hinnanteee2c142012-04-11 20:14:21 +00001437 memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001438{
1439 return __o->fetch_sub(__op, __m);
1440}
1441
1442template <class _Tp>
1443inline _LIBCPP_INLINE_VISIBILITY
1444_Tp*
Howard Hinnanteee2c142012-04-11 20:14:21 +00001445atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001446{
1447 return __o->fetch_sub(__op, __m);
1448}
1449
1450// atomic_fetch_and
1451
1452template <class _Tp>
1453inline _LIBCPP_INLINE_VISIBILITY
1454typename enable_if
1455<
1456 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1457 _Tp
1458>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001459atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001460{
1461 return __o->fetch_and(__op);
1462}
1463
1464template <class _Tp>
1465inline _LIBCPP_INLINE_VISIBILITY
1466typename enable_if
1467<
1468 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1469 _Tp
1470>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001471atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001472{
1473 return __o->fetch_and(__op);
1474}
1475
1476// atomic_fetch_and_explicit
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_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001486{
1487 return __o->fetch_and(__op, __m);
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_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001498{
1499 return __o->fetch_and(__op, __m);
1500}
1501
1502// atomic_fetch_or
1503
1504template <class _Tp>
1505inline _LIBCPP_INLINE_VISIBILITY
1506typename enable_if
1507<
1508 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1509 _Tp
1510>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001511atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001512{
1513 return __o->fetch_or(__op);
1514}
1515
1516template <class _Tp>
1517inline _LIBCPP_INLINE_VISIBILITY
1518typename enable_if
1519<
1520 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1521 _Tp
1522>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001523atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001524{
1525 return __o->fetch_or(__op);
1526}
1527
1528// atomic_fetch_or_explicit
1529
1530template <class _Tp>
1531inline _LIBCPP_INLINE_VISIBILITY
1532typename enable_if
1533<
1534 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1535 _Tp
1536>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001537atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001538{
1539 return __o->fetch_or(__op, __m);
1540}
1541
1542template <class _Tp>
1543inline _LIBCPP_INLINE_VISIBILITY
1544typename enable_if
1545<
1546 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1547 _Tp
1548>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001549atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001550{
1551 return __o->fetch_or(__op, __m);
1552}
1553
1554// atomic_fetch_xor
1555
1556template <class _Tp>
1557inline _LIBCPP_INLINE_VISIBILITY
1558typename enable_if
1559<
1560 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1561 _Tp
1562>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001563atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001564{
1565 return __o->fetch_xor(__op);
1566}
1567
1568template <class _Tp>
1569inline _LIBCPP_INLINE_VISIBILITY
1570typename enable_if
1571<
1572 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1573 _Tp
1574>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001575atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001576{
1577 return __o->fetch_xor(__op);
1578}
1579
1580// atomic_fetch_xor_explicit
1581
1582template <class _Tp>
1583inline _LIBCPP_INLINE_VISIBILITY
1584typename enable_if
1585<
1586 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1587 _Tp
1588>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001589atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001590{
1591 return __o->fetch_xor(__op, __m);
1592}
1593
1594template <class _Tp>
1595inline _LIBCPP_INLINE_VISIBILITY
1596typename enable_if
1597<
1598 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1599 _Tp
1600>::type
Howard Hinnanteee2c142012-04-11 20:14:21 +00001601atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
Howard Hinnant138f5922010-12-07 20:46:14 +00001602{
1603 return __o->fetch_xor(__op, __m);
1604}
Howard Hinnant7bfaeb82010-12-06 23:10:08 +00001605
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001606// flag type and operations
1607
1608typedef struct atomic_flag
1609{
David Chisnall26ed3f42011-12-19 11:44:20 +00001610 _Atomic(bool) __a_;
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001611
1612 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001613 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001614 {return __c11_atomic_exchange(&__a_, true, __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001615 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001616 bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001617 {return __c11_atomic_exchange(&__a_, true, __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001618 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001619 void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001620 {__c11_atomic_store(&__a_, false, __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001621 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001622 void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
Richard Smith27a4a972012-04-11 18:55:46 +00001623 {__c11_atomic_store(&__a_, false, __m);}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001624
1625 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3d284222013-05-02 20:18:43 +00001626#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
1627 atomic_flag() _NOEXCEPT = default;
1628#else
1629 atomic_flag() _NOEXCEPT : __a_() {}
1630#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
1631
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001632 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanteee2c142012-04-11 20:14:21 +00001633 atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {}
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001634
1635#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1636 atomic_flag(const atomic_flag&) = delete;
1637 atomic_flag& operator=(const atomic_flag&) = delete;
1638 atomic_flag& operator=(const atomic_flag&) volatile = delete;
1639#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1640private:
1641 atomic_flag(const atomic_flag&);
1642 atomic_flag& operator=(const atomic_flag&);
1643 atomic_flag& operator=(const atomic_flag&) volatile;
1644#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1645} atomic_flag;
1646
1647inline _LIBCPP_INLINE_VISIBILITY
1648bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001649atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001650{
1651 return __o->test_and_set();
1652}
1653
1654inline _LIBCPP_INLINE_VISIBILITY
1655bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001656atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001657{
1658 return __o->test_and_set();
1659}
1660
1661inline _LIBCPP_INLINE_VISIBILITY
1662bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001663atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001664{
1665 return __o->test_and_set(__m);
1666}
1667
1668inline _LIBCPP_INLINE_VISIBILITY
1669bool
Howard Hinnanteee2c142012-04-11 20:14:21 +00001670atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001671{
1672 return __o->test_and_set(__m);
1673}
1674
1675inline _LIBCPP_INLINE_VISIBILITY
1676void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001677atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001678{
1679 __o->clear();
1680}
1681
1682inline _LIBCPP_INLINE_VISIBILITY
1683void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001684atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001685{
1686 __o->clear();
1687}
1688
1689inline _LIBCPP_INLINE_VISIBILITY
1690void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001691atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001692{
1693 __o->clear(__m);
1694}
1695
1696inline _LIBCPP_INLINE_VISIBILITY
1697void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001698atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001699{
1700 __o->clear(__m);
1701}
1702
1703// fences
1704
1705inline _LIBCPP_INLINE_VISIBILITY
1706void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001707atomic_thread_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001708{
Richard Smith27a4a972012-04-11 18:55:46 +00001709 __c11_atomic_thread_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001710}
1711
1712inline _LIBCPP_INLINE_VISIBILITY
1713void
Howard Hinnanteee2c142012-04-11 20:14:21 +00001714atomic_signal_fence(memory_order __m) _NOEXCEPT
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001715{
Richard Smith27a4a972012-04-11 18:55:46 +00001716 __c11_atomic_signal_fence(__m);
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001717}
1718
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001719// Atomics for standard typedef types
1720
Howard Hinnantf0af8d92013-01-04 18:58:50 +00001721typedef atomic<bool> atomic_bool;
Howard Hinnant96e4cd62010-12-07 23:24:41 +00001722typedef atomic<char> atomic_char;
1723typedef atomic<signed char> atomic_schar;
1724typedef atomic<unsigned char> atomic_uchar;
1725typedef atomic<short> atomic_short;
1726typedef atomic<unsigned short> atomic_ushort;
1727typedef atomic<int> atomic_int;
1728typedef atomic<unsigned int> atomic_uint;
1729typedef atomic<long> atomic_long;
1730typedef atomic<unsigned long> atomic_ulong;
1731typedef atomic<long long> atomic_llong;
1732typedef atomic<unsigned long long> atomic_ullong;
1733typedef atomic<char16_t> atomic_char16_t;
1734typedef atomic<char32_t> atomic_char32_t;
1735typedef atomic<wchar_t> atomic_wchar_t;
1736
1737typedef atomic<int_least8_t> atomic_int_least8_t;
1738typedef atomic<uint_least8_t> atomic_uint_least8_t;
1739typedef atomic<int_least16_t> atomic_int_least16_t;
1740typedef atomic<uint_least16_t> atomic_uint_least16_t;
1741typedef atomic<int_least32_t> atomic_int_least32_t;
1742typedef atomic<uint_least32_t> atomic_uint_least32_t;
1743typedef atomic<int_least64_t> atomic_int_least64_t;
1744typedef atomic<uint_least64_t> atomic_uint_least64_t;
1745
1746typedef atomic<int_fast8_t> atomic_int_fast8_t;
1747typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
1748typedef atomic<int_fast16_t> atomic_int_fast16_t;
1749typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1750typedef atomic<int_fast32_t> atomic_int_fast32_t;
1751typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1752typedef atomic<int_fast64_t> atomic_int_fast64_t;
1753typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1754
1755typedef atomic<intptr_t> atomic_intptr_t;
1756typedef atomic<uintptr_t> atomic_uintptr_t;
1757typedef atomic<size_t> atomic_size_t;
1758typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1759typedef atomic<intmax_t> atomic_intmax_t;
1760typedef atomic<uintmax_t> atomic_uintmax_t;
1761
Howard Hinnantf1f066a2010-09-29 21:20:03 +00001762#define ATOMIC_FLAG_INIT {false}
Howard Hinnant953c31d2010-10-04 18:52:54 +00001763#define ATOMIC_VAR_INIT(__v) {__v}
1764
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001765// lock-free property
Howard Hinnant953c31d2010-10-04 18:52:54 +00001766
Howard Hinnant931e3402013-01-21 20:39:41 +00001767#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
1768#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
1769#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1770#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1771#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1772#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
1773#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
1774#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
1775#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
1776#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
Howard Hinnant6ac60f82010-12-08 17:20:28 +00001777
Howard Hinnant14fdaba2011-03-31 16:39:39 +00001778#endif // !__has_feature(cxx_atomic)
1779
Howard Hinnant71be7292010-09-27 21:17:38 +00001780_LIBCPP_END_NAMESPACE_STD
1781
1782#endif // _LIBCPP_ATOMIC