]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/atomic
Import new libc++ to vendor branch.
[FreeBSD/FreeBSD.git] / include / atomic
1 // -*- 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
17 namespace std
18 {
19
20 // order and consistency
21
22 typedef enum memory_order
23 {
24     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
30 } memory_order;
31
32 template <class T> T kill_dependency(T y) noexcept;
33
34 // lock-free property
35
36 #define ATOMIC_BOOL_LOCK_FREE unspecified
37 #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
45 #define ATOMIC_POINTER_LOCK_FREE unspecified
46
47 // flag type and operations
48
49 typedef struct atomic_flag
50 {
51     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;
56     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
61 bool
62     atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
63
64 bool
65     atomic_flag_test_and_set(atomic_flag* obj) noexcept;
66
67 bool
68     atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
69                                       memory_order m) noexcept;
70
71 bool
72     atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
73
74 void
75     atomic_flag_clear(volatile atomic_flag* obj) noexcept;
76
77 void
78     atomic_flag_clear(atomic_flag* obj) noexcept;
79
80 void
81     atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
82
83 void
84     atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
85
86 #define ATOMIC_FLAG_INIT see below
87 #define ATOMIC_VAR_INIT(value) see below
88
89 template <class T>
90 struct atomic
91 {
92     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;
102     bool compare_exchange_weak(T& expc, T desr,
103                                memory_order s, memory_order f) volatile noexcept;
104     bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
105     bool compare_exchange_strong(T& expc, T desr,
106                                  memory_order s, memory_order f) volatile noexcept;
107     bool compare_exchange_strong(T& expc, T desr,
108                                  memory_order s, memory_order f) noexcept;
109     bool compare_exchange_weak(T& expc, T desr,
110                                memory_order m = memory_order_seq_cst) volatile noexcept;
111     bool compare_exchange_weak(T& expc, T desr,
112                                memory_order m = memory_order_seq_cst) noexcept;
113     bool compare_exchange_strong(T& expc, T desr,
114                                 memory_order m = memory_order_seq_cst) volatile noexcept;
115     bool compare_exchange_strong(T& expc, T desr,
116                                  memory_order m = memory_order_seq_cst) noexcept;
117
118     atomic() noexcept = default;
119     constexpr atomic(T desr) noexcept;
120     atomic(const atomic&) = delete;
121     atomic& operator=(const atomic&) = delete;
122     atomic& operator=(const atomic&) volatile = delete;
123     T operator=(T) volatile noexcept;
124     T operator=(T) noexcept;
125 };
126
127 template <>
128 struct atomic<integral>
129 {
130     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;
138     integral exchange(integral desr,
139                       memory_order m = memory_order_seq_cst) volatile noexcept;
140     integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
141     bool compare_exchange_weak(integral& expc, integral desr,
142                                memory_order s, memory_order f) volatile noexcept;
143     bool compare_exchange_weak(integral& expc, integral desr,
144                                memory_order s, memory_order f) noexcept;
145     bool compare_exchange_strong(integral& expc, integral desr,
146                                  memory_order s, memory_order f) volatile noexcept;
147     bool compare_exchange_strong(integral& expc, integral desr,
148                                  memory_order s, memory_order f) noexcept;
149     bool compare_exchange_weak(integral& expc, integral desr,
150                                memory_order m = memory_order_seq_cst) volatile noexcept;
151     bool compare_exchange_weak(integral& expc, integral desr,
152                                memory_order m = memory_order_seq_cst) noexcept;
153     bool compare_exchange_strong(integral& expc, integral desr,
154                                 memory_order m = memory_order_seq_cst) volatile noexcept;
155     bool compare_exchange_strong(integral& expc, integral desr,
156                                  memory_order m = memory_order_seq_cst) noexcept;
157
158     integral
159         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;
161     integral
162         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;
164     integral
165         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;
167     integral
168         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;
170     integral
171         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;
173
174     atomic() noexcept = default;
175     constexpr atomic(integral desr) noexcept;
176     atomic(const atomic&) = delete;
177     atomic& operator=(const atomic&) = delete;
178     atomic& operator=(const atomic&) volatile = delete;
179     integral operator=(integral desr) volatile noexcept;
180     integral operator=(integral desr) noexcept;
181
182     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;
200 };
201
202 template <class T>
203 struct atomic<T*>
204 {
205     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;
215     bool compare_exchange_weak(T*& expc, T* desr,
216                                memory_order s, memory_order f) volatile noexcept;
217     bool compare_exchange_weak(T*& expc, T* desr,
218                                memory_order s, memory_order f) noexcept;
219     bool compare_exchange_strong(T*& expc, T* desr,
220                                  memory_order s, memory_order f) volatile noexcept;
221     bool compare_exchange_strong(T*& expc, T* desr,
222                                  memory_order s, memory_order f) noexcept;
223     bool compare_exchange_weak(T*& expc, T* desr,
224                                memory_order m = memory_order_seq_cst) volatile noexcept;
225     bool compare_exchange_weak(T*& expc, T* desr,
226                                memory_order m = memory_order_seq_cst) noexcept;
227     bool compare_exchange_strong(T*& expc, T* desr,
228                                 memory_order m = memory_order_seq_cst) volatile noexcept;
229     bool compare_exchange_strong(T*& expc, T* desr,
230                                  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;
235
236     atomic() noexcept = default;
237     constexpr atomic(T* desr) noexcept;
238     atomic(const atomic&) = delete;
239     atomic& operator=(const atomic&) = delete;
240     atomic& operator=(const atomic&) volatile = delete;
241
242     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;
256 };
257
258
259 template <class T>
260     bool
261     atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
262
263 template <class T>
264     bool
265     atomic_is_lock_free(const atomic<T>* obj) noexcept;
266
267 template <class T>
268     void
269     atomic_init(volatile atomic<T>* obj, T desr) noexcept;
270
271 template <class T>
272     void
273     atomic_init(atomic<T>* obj, T desr) noexcept;
274
275 template <class T>
276     void
277     atomic_store(volatile atomic<T>* obj, T desr) noexcept;
278
279 template <class T>
280     void
281     atomic_store(atomic<T>* obj, T desr) noexcept;
282
283 template <class T>
284     void
285     atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
286
287 template <class T>
288     void
289     atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
290
291 template <class T>
292     T
293     atomic_load(const volatile atomic<T>* obj) noexcept;
294
295 template <class T>
296     T
297     atomic_load(const atomic<T>* obj) noexcept;
298
299 template <class T>
300     T
301     atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
302
303 template <class T>
304     T
305     atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
306
307 template <class T>
308     T
309     atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
310
311 template <class T>
312     T
313     atomic_exchange(atomic<T>* obj, T desr) noexcept;
314
315 template <class T>
316     T
317     atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
318
319 template <class T>
320     T
321     atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
322
323 template <class T>
324     bool
325     atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
326
327 template <class T>
328     bool
329     atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
330
331 template <class T>
332     bool
333     atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
334
335 template <class T>
336     bool
337     atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
338
339 template <class T>
340     bool
341     atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
342                                           T desr,
343                                           memory_order s, memory_order f) noexcept;
344
345 template <class T>
346     bool
347     atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
348                                           memory_order s, memory_order f) noexcept;
349
350 template <class T>
351     bool
352     atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
353                                             T* expc, T desr,
354                                             memory_order s, memory_order f) noexcept;
355
356 template <class T>
357     bool
358     atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
359                                             T desr,
360                                             memory_order s, memory_order f) noexcept;
361
362 template <class Integral>
363     Integral
364     atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
365
366 template <class Integral>
367     Integral
368     atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
369
370 template <class Integral>
371     Integral
372     atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
373                               memory_order m) noexcept;
374 template <class Integral>
375     Integral
376     atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
377                               memory_order m) noexcept;
378 template <class Integral>
379     Integral
380     atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
381
382 template <class Integral>
383     Integral
384     atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
385
386 template <class Integral>
387     Integral
388     atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
389                               memory_order m) noexcept;
390 template <class Integral>
391     Integral
392     atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
393                               memory_order m) noexcept;
394 template <class Integral>
395     Integral
396     atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
397
398 template <class Integral>
399     Integral
400     atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
401
402 template <class Integral>
403     Integral
404     atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
405                               memory_order m) noexcept;
406 template <class Integral>
407     Integral
408     atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
409                               memory_order m) noexcept;
410 template <class Integral>
411     Integral
412     atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
413
414 template <class Integral>
415     Integral
416     atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
417
418 template <class Integral>
419     Integral
420     atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
421                              memory_order m) noexcept;
422 template <class Integral>
423     Integral
424     atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
425                              memory_order m) noexcept;
426 template <class Integral>
427     Integral
428     atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
429
430 template <class Integral>
431     Integral
432     atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
433
434 template <class Integral>
435     Integral
436     atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
437                               memory_order m) noexcept;
438 template <class Integral>
439     Integral
440     atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
441                               memory_order m) noexcept;
442
443 template <class T>
444     T*
445     atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
446
447 template <class T>
448     T*
449     atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
450
451 template <class T>
452     T*
453     atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
454                               memory_order m) noexcept;
455 template <class T>
456     T*
457     atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
458
459 template <class T>
460     T*
461     atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
462
463 template <class T>
464     T*
465     atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
466
467 template <class T>
468     T*
469     atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
470                               memory_order m) noexcept;
471 template <class T>
472     T*
473     atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
474
475 // Atomics for standard typedef types
476
477 typedef atomic<bool>               atomic_bool;
478 typedef atomic<char>               atomic_char;
479 typedef atomic<signed char>        atomic_schar;
480 typedef atomic<unsigned char>      atomic_uchar;
481 typedef atomic<short>              atomic_short;
482 typedef atomic<unsigned short>     atomic_ushort;
483 typedef atomic<int>                atomic_int;
484 typedef atomic<unsigned int>       atomic_uint;
485 typedef atomic<long>               atomic_long;
486 typedef atomic<unsigned long>      atomic_ulong;
487 typedef atomic<long long>          atomic_llong;
488 typedef atomic<unsigned long long> atomic_ullong;
489 typedef atomic<char16_t>           atomic_char16_t;
490 typedef atomic<char32_t>           atomic_char32_t;
491 typedef atomic<wchar_t>            atomic_wchar_t;
492
493 typedef atomic<int_least8_t>   atomic_int_least8_t;
494 typedef atomic<uint_least8_t>  atomic_uint_least8_t;
495 typedef atomic<int_least16_t>  atomic_int_least16_t;
496 typedef atomic<uint_least16_t> atomic_uint_least16_t;
497 typedef atomic<int_least32_t>  atomic_int_least32_t;
498 typedef atomic<uint_least32_t> atomic_uint_least32_t;
499 typedef atomic<int_least64_t>  atomic_int_least64_t;
500 typedef atomic<uint_least64_t> atomic_uint_least64_t;
501
502 typedef atomic<int_fast8_t>   atomic_int_fast8_t;
503 typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
504 typedef atomic<int_fast16_t>  atomic_int_fast16_t;
505 typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
506 typedef atomic<int_fast32_t>  atomic_int_fast32_t;
507 typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
508 typedef atomic<int_fast64_t>  atomic_int_fast64_t;
509 typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
510
511 typedef atomic<intptr_t>  atomic_intptr_t;
512 typedef atomic<uintptr_t> atomic_uintptr_t;
513 typedef atomic<size_t>    atomic_size_t;
514 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
515 typedef atomic<intmax_t>  atomic_intmax_t;
516 typedef atomic<uintmax_t> atomic_uintmax_t;
517
518 // fences
519
520 void atomic_thread_fence(memory_order m) noexcept;
521 void atomic_signal_fence(memory_order m) noexcept;
522
523 }  // std
524
525 */
526
527 #include <__config>
528 #include <cstddef>
529 #include <cstdint>
530 #include <type_traits>
531
532 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
533 #pragma GCC system_header
534 #endif
535
536 _LIBCPP_BEGIN_NAMESPACE_STD
537
538 #if !__has_feature(cxx_atomic)
539 #error <atomic> is not implemented
540 #else
541
542 typedef 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
548 template <class _Tp>
549 inline _LIBCPP_INLINE_VISIBILITY
550 _Tp
551 kill_dependency(_Tp __y) _NOEXCEPT
552 {
553     return __y;
554 }
555
556 // general atomic<T>
557
558 template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
559 struct __atomic_base  // false
560 {
561     mutable _Atomic(_Tp) __a_;
562
563     _LIBCPP_INLINE_VISIBILITY
564     bool is_lock_free() const volatile _NOEXCEPT
565         {return __c11_atomic_is_lock_free(sizeof(_Tp));}
566     _LIBCPP_INLINE_VISIBILITY
567     bool is_lock_free() const _NOEXCEPT
568         {return __c11_atomic_is_lock_free(sizeof(_Tp));}
569     _LIBCPP_INLINE_VISIBILITY
570     void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
571         {__c11_atomic_store(&__a_, __d, __m);}
572     _LIBCPP_INLINE_VISIBILITY
573     void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
574         {__c11_atomic_store(&__a_, __d, __m);}
575     _LIBCPP_INLINE_VISIBILITY
576     _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
577         {return __c11_atomic_load(&__a_, __m);}
578     _LIBCPP_INLINE_VISIBILITY
579     _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
580         {return __c11_atomic_load(&__a_, __m);}
581     _LIBCPP_INLINE_VISIBILITY
582     operator _Tp() const volatile _NOEXCEPT {return load();}
583     _LIBCPP_INLINE_VISIBILITY
584     operator _Tp() const _NOEXCEPT          {return load();}
585     _LIBCPP_INLINE_VISIBILITY
586     _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
587         {return __c11_atomic_exchange(&__a_, __d, __m);}
588     _LIBCPP_INLINE_VISIBILITY
589     _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
590         {return __c11_atomic_exchange(&__a_, __d, __m);}
591     _LIBCPP_INLINE_VISIBILITY
592     bool compare_exchange_weak(_Tp& __e, _Tp __d,
593                                memory_order __s, memory_order __f) volatile _NOEXCEPT
594         {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
595     _LIBCPP_INLINE_VISIBILITY
596     bool compare_exchange_weak(_Tp& __e, _Tp __d,
597                                memory_order __s, memory_order __f) _NOEXCEPT
598         {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
599     _LIBCPP_INLINE_VISIBILITY
600     bool compare_exchange_strong(_Tp& __e, _Tp __d,
601                                  memory_order __s, memory_order __f) volatile _NOEXCEPT
602         {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
603     _LIBCPP_INLINE_VISIBILITY
604     bool compare_exchange_strong(_Tp& __e, _Tp __d,
605                                  memory_order __s, memory_order __f) _NOEXCEPT
606         {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
607     _LIBCPP_INLINE_VISIBILITY
608     bool compare_exchange_weak(_Tp& __e, _Tp __d,
609                               memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
610         {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
611     _LIBCPP_INLINE_VISIBILITY
612     bool compare_exchange_weak(_Tp& __e, _Tp __d,
613                                memory_order __m = memory_order_seq_cst) _NOEXCEPT
614         {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
615     _LIBCPP_INLINE_VISIBILITY
616     bool compare_exchange_strong(_Tp& __e, _Tp __d,
617                               memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
618         {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
619     _LIBCPP_INLINE_VISIBILITY
620     bool compare_exchange_strong(_Tp& __e, _Tp __d,
621                                  memory_order __m = memory_order_seq_cst) _NOEXCEPT
622         {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
623
624     _LIBCPP_INLINE_VISIBILITY
625     __atomic_base() _NOEXCEPT {} // = default;
626     _LIBCPP_INLINE_VISIBILITY
627     _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
628 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
629     __atomic_base(const __atomic_base&) = delete;
630     __atomic_base& operator=(const __atomic_base&) = delete;
631     __atomic_base& operator=(const __atomic_base&) volatile = delete;
632 #else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
633 private:
634     __atomic_base(const __atomic_base&);
635     __atomic_base& operator=(const __atomic_base&);
636     __atomic_base& operator=(const __atomic_base&) volatile;
637 #endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
638 };
639
640 // atomic<Integral>
641
642 template <class _Tp>
643 struct __atomic_base<_Tp, true>
644     : public __atomic_base<_Tp, false>
645 {
646     typedef __atomic_base<_Tp, false> __base;
647     _LIBCPP_INLINE_VISIBILITY
648     __atomic_base() _NOEXCEPT {} // = default;
649     _LIBCPP_INLINE_VISIBILITY
650     _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
651
652     _LIBCPP_INLINE_VISIBILITY
653     _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
654         {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
655     _LIBCPP_INLINE_VISIBILITY
656     _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
657         {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
658     _LIBCPP_INLINE_VISIBILITY
659     _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
660         {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
661     _LIBCPP_INLINE_VISIBILITY
662     _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
663         {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
664     _LIBCPP_INLINE_VISIBILITY
665     _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
666         {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
667     _LIBCPP_INLINE_VISIBILITY
668     _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
669         {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
670     _LIBCPP_INLINE_VISIBILITY
671     _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
672         {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
673     _LIBCPP_INLINE_VISIBILITY
674     _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
675         {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
676     _LIBCPP_INLINE_VISIBILITY
677     _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
678         {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
679     _LIBCPP_INLINE_VISIBILITY
680     _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
681         {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
682
683     _LIBCPP_INLINE_VISIBILITY
684     _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
685     _LIBCPP_INLINE_VISIBILITY
686     _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
687     _LIBCPP_INLINE_VISIBILITY
688     _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
689     _LIBCPP_INLINE_VISIBILITY
690     _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
691     _LIBCPP_INLINE_VISIBILITY
692     _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
693     _LIBCPP_INLINE_VISIBILITY
694     _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
695     _LIBCPP_INLINE_VISIBILITY
696     _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
697     _LIBCPP_INLINE_VISIBILITY
698     _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
699     _LIBCPP_INLINE_VISIBILITY
700     _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
701     _LIBCPP_INLINE_VISIBILITY
702     _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
703     _LIBCPP_INLINE_VISIBILITY
704     _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
705     _LIBCPP_INLINE_VISIBILITY
706     _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
707     _LIBCPP_INLINE_VISIBILITY
708     _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
709     _LIBCPP_INLINE_VISIBILITY
710     _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
711     _LIBCPP_INLINE_VISIBILITY
712     _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
713     _LIBCPP_INLINE_VISIBILITY
714     _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
715     _LIBCPP_INLINE_VISIBILITY
716     _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
717     _LIBCPP_INLINE_VISIBILITY
718     _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
719 };
720
721 // atomic<T>
722
723 template <class _Tp>
724 struct atomic
725     : public __atomic_base<_Tp>
726 {
727     typedef __atomic_base<_Tp> __base;
728     _LIBCPP_INLINE_VISIBILITY
729     atomic() _NOEXCEPT {} // = default;
730     _LIBCPP_INLINE_VISIBILITY
731     _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
732
733     _LIBCPP_INLINE_VISIBILITY
734     _Tp operator=(_Tp __d) volatile _NOEXCEPT
735         {__base::store(__d); return __d;}
736     _LIBCPP_INLINE_VISIBILITY
737     _Tp operator=(_Tp __d) _NOEXCEPT
738         {__base::store(__d); return __d;}
739 };
740
741 // atomic<T*>
742
743 template <class _Tp>
744 struct atomic<_Tp*>
745     : public __atomic_base<_Tp*>
746 {
747     typedef __atomic_base<_Tp*> __base;
748     _LIBCPP_INLINE_VISIBILITY
749     atomic() _NOEXCEPT {} // = default;
750     _LIBCPP_INLINE_VISIBILITY
751     _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
752
753     _LIBCPP_INLINE_VISIBILITY
754     _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
755         {__base::store(__d); return __d;}
756     _LIBCPP_INLINE_VISIBILITY
757     _Tp* operator=(_Tp* __d) _NOEXCEPT
758         {__base::store(__d); return __d;}
759
760     _LIBCPP_INLINE_VISIBILITY
761     _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
762                                                                         volatile _NOEXCEPT
763         {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
764     _LIBCPP_INLINE_VISIBILITY
765     _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
766         {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
767     _LIBCPP_INLINE_VISIBILITY
768     _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
769                                                                         volatile _NOEXCEPT
770         {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
771     _LIBCPP_INLINE_VISIBILITY
772     _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
773         {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
774
775     _LIBCPP_INLINE_VISIBILITY
776     _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
777     _LIBCPP_INLINE_VISIBILITY
778     _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
779     _LIBCPP_INLINE_VISIBILITY
780     _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
781     _LIBCPP_INLINE_VISIBILITY
782     _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
783     _LIBCPP_INLINE_VISIBILITY
784     _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
785     _LIBCPP_INLINE_VISIBILITY
786     _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
787     _LIBCPP_INLINE_VISIBILITY
788     _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
789     _LIBCPP_INLINE_VISIBILITY
790     _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
791     _LIBCPP_INLINE_VISIBILITY
792     _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
793     _LIBCPP_INLINE_VISIBILITY
794     _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
795     _LIBCPP_INLINE_VISIBILITY
796     _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
797     _LIBCPP_INLINE_VISIBILITY
798     _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
799 };
800
801 // atomic_is_lock_free
802
803 template <class _Tp>
804 inline _LIBCPP_INLINE_VISIBILITY
805 bool
806 atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
807 {
808     return __o->is_lock_free();
809 }
810
811 template <class _Tp>
812 inline _LIBCPP_INLINE_VISIBILITY
813 bool
814 atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
815 {
816     return __o->is_lock_free();
817 }
818
819 // atomic_init
820
821 template <class _Tp>
822 inline _LIBCPP_INLINE_VISIBILITY
823 void
824 atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
825 {
826     __c11_atomic_init(&__o->__a_, __d);
827 }
828
829 template <class _Tp>
830 inline _LIBCPP_INLINE_VISIBILITY
831 void
832 atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
833 {
834     __c11_atomic_init(&__o->__a_, __d);
835 }
836
837 // atomic_store
838
839 template <class _Tp>
840 inline _LIBCPP_INLINE_VISIBILITY
841 void
842 atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
843 {
844     __o->store(__d);
845 }
846
847 template <class _Tp>
848 inline _LIBCPP_INLINE_VISIBILITY
849 void
850 atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
851 {
852     __o->store(__d);
853 }
854
855 // atomic_store_explicit
856
857 template <class _Tp>
858 inline _LIBCPP_INLINE_VISIBILITY
859 void
860 atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
861 {
862     __o->store(__d, __m);
863 }
864
865 template <class _Tp>
866 inline _LIBCPP_INLINE_VISIBILITY
867 void
868 atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
869 {
870     __o->store(__d, __m);
871 }
872
873 // atomic_load
874
875 template <class _Tp>
876 inline _LIBCPP_INLINE_VISIBILITY
877 _Tp
878 atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
879 {
880     return __o->load();
881 }
882
883 template <class _Tp>
884 inline _LIBCPP_INLINE_VISIBILITY
885 _Tp
886 atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
887 {
888     return __o->load();
889 }
890
891 // atomic_load_explicit
892
893 template <class _Tp>
894 inline _LIBCPP_INLINE_VISIBILITY
895 _Tp
896 atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
897 {
898     return __o->load(__m);
899 }
900
901 template <class _Tp>
902 inline _LIBCPP_INLINE_VISIBILITY
903 _Tp
904 atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
905 {
906     return __o->load(__m);
907 }
908
909 // atomic_exchange
910
911 template <class _Tp>
912 inline _LIBCPP_INLINE_VISIBILITY
913 _Tp
914 atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
915 {
916     return __o->exchange(__d);
917 }
918
919 template <class _Tp>
920 inline _LIBCPP_INLINE_VISIBILITY
921 _Tp
922 atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
923 {
924     return __o->exchange(__d);
925 }
926
927 // atomic_exchange_explicit
928
929 template <class _Tp>
930 inline _LIBCPP_INLINE_VISIBILITY
931 _Tp
932 atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
933 {
934     return __o->exchange(__d, __m);
935 }
936
937 template <class _Tp>
938 inline _LIBCPP_INLINE_VISIBILITY
939 _Tp
940 atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
941 {
942     return __o->exchange(__d, __m);
943 }
944
945 // atomic_compare_exchange_weak
946
947 template <class _Tp>
948 inline _LIBCPP_INLINE_VISIBILITY
949 bool
950 atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
951 {
952     return __o->compare_exchange_weak(*__e, __d);
953 }
954
955 template <class _Tp>
956 inline _LIBCPP_INLINE_VISIBILITY
957 bool
958 atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
959 {
960     return __o->compare_exchange_weak(*__e, __d);
961 }
962
963 // atomic_compare_exchange_strong
964
965 template <class _Tp>
966 inline _LIBCPP_INLINE_VISIBILITY
967 bool
968 atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
969 {
970     return __o->compare_exchange_strong(*__e, __d);
971 }
972
973 template <class _Tp>
974 inline _LIBCPP_INLINE_VISIBILITY
975 bool
976 atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
977 {
978     return __o->compare_exchange_strong(*__e, __d);
979 }
980
981 // atomic_compare_exchange_weak_explicit
982
983 template <class _Tp>
984 inline _LIBCPP_INLINE_VISIBILITY
985 bool
986 atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
987                                       _Tp __d,
988                                       memory_order __s, memory_order __f) _NOEXCEPT
989 {
990     return __o->compare_exchange_weak(*__e, __d, __s, __f);
991 }
992
993 template <class _Tp>
994 inline _LIBCPP_INLINE_VISIBILITY
995 bool
996 atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
997                                       memory_order __s, memory_order __f) _NOEXCEPT
998 {
999     return __o->compare_exchange_weak(*__e, __d, __s, __f);
1000 }
1001
1002 // atomic_compare_exchange_strong_explicit
1003
1004 template <class _Tp>
1005 inline _LIBCPP_INLINE_VISIBILITY
1006 bool
1007 atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1008                                         _Tp* __e, _Tp __d,
1009                                         memory_order __s, memory_order __f) _NOEXCEPT
1010 {
1011     return __o->compare_exchange_strong(*__e, __d, __s, __f);
1012 }
1013
1014 template <class _Tp>
1015 inline _LIBCPP_INLINE_VISIBILITY
1016 bool
1017 atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1018                                         _Tp __d,
1019                                         memory_order __s, memory_order __f) _NOEXCEPT
1020 {
1021     return __o->compare_exchange_strong(*__e, __d, __s, __f);
1022 }
1023
1024 // atomic_fetch_add
1025
1026 template <class _Tp>
1027 inline _LIBCPP_INLINE_VISIBILITY
1028 typename enable_if
1029 <
1030     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1031     _Tp
1032 >::type
1033 atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1034 {
1035     return __o->fetch_add(__op);
1036 }
1037
1038 template <class _Tp>
1039 inline _LIBCPP_INLINE_VISIBILITY
1040 typename enable_if
1041 <
1042     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1043     _Tp
1044 >::type
1045 atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1046 {
1047     return __o->fetch_add(__op);
1048 }
1049
1050 template <class _Tp>
1051 inline _LIBCPP_INLINE_VISIBILITY
1052 _Tp*
1053 atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1054 {
1055     return __o->fetch_add(__op);
1056 }
1057
1058 template <class _Tp>
1059 inline _LIBCPP_INLINE_VISIBILITY
1060 _Tp*
1061 atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1062 {
1063     return __o->fetch_add(__op);
1064 }
1065
1066 // atomic_fetch_add_explicit
1067
1068 template <class _Tp>
1069 inline _LIBCPP_INLINE_VISIBILITY
1070 typename enable_if
1071 <
1072     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1073     _Tp
1074 >::type
1075 atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1076 {
1077     return __o->fetch_add(__op, __m);
1078 }
1079
1080 template <class _Tp>
1081 inline _LIBCPP_INLINE_VISIBILITY
1082 typename enable_if
1083 <
1084     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1085     _Tp
1086 >::type
1087 atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1088 {
1089     return __o->fetch_add(__op, __m);
1090 }
1091
1092 template <class _Tp>
1093 inline _LIBCPP_INLINE_VISIBILITY
1094 _Tp*
1095 atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1096                           memory_order __m) _NOEXCEPT
1097 {
1098     return __o->fetch_add(__op, __m);
1099 }
1100
1101 template <class _Tp>
1102 inline _LIBCPP_INLINE_VISIBILITY
1103 _Tp*
1104 atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
1105 {
1106     return __o->fetch_add(__op, __m);
1107 }
1108
1109 // atomic_fetch_sub
1110
1111 template <class _Tp>
1112 inline _LIBCPP_INLINE_VISIBILITY
1113 typename enable_if
1114 <
1115     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1116     _Tp
1117 >::type
1118 atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1119 {
1120     return __o->fetch_sub(__op);
1121 }
1122
1123 template <class _Tp>
1124 inline _LIBCPP_INLINE_VISIBILITY
1125 typename enable_if
1126 <
1127     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1128     _Tp
1129 >::type
1130 atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1131 {
1132     return __o->fetch_sub(__op);
1133 }
1134
1135 template <class _Tp>
1136 inline _LIBCPP_INLINE_VISIBILITY
1137 _Tp*
1138 atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1139 {
1140     return __o->fetch_sub(__op);
1141 }
1142
1143 template <class _Tp>
1144 inline _LIBCPP_INLINE_VISIBILITY
1145 _Tp*
1146 atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1147 {
1148     return __o->fetch_sub(__op);
1149 }
1150
1151 // atomic_fetch_sub_explicit
1152
1153 template <class _Tp>
1154 inline _LIBCPP_INLINE_VISIBILITY
1155 typename enable_if
1156 <
1157     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1158     _Tp
1159 >::type
1160 atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1161 {
1162     return __o->fetch_sub(__op, __m);
1163 }
1164
1165 template <class _Tp>
1166 inline _LIBCPP_INLINE_VISIBILITY
1167 typename enable_if
1168 <
1169     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1170     _Tp
1171 >::type
1172 atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1173 {
1174     return __o->fetch_sub(__op, __m);
1175 }
1176
1177 template <class _Tp>
1178 inline _LIBCPP_INLINE_VISIBILITY
1179 _Tp*
1180 atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1181                           memory_order __m) _NOEXCEPT
1182 {
1183     return __o->fetch_sub(__op, __m);
1184 }
1185
1186 template <class _Tp>
1187 inline _LIBCPP_INLINE_VISIBILITY
1188 _Tp*
1189 atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
1190 {
1191     return __o->fetch_sub(__op, __m);
1192 }
1193
1194 // atomic_fetch_and
1195
1196 template <class _Tp>
1197 inline _LIBCPP_INLINE_VISIBILITY
1198 typename enable_if
1199 <
1200     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1201     _Tp
1202 >::type
1203 atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1204 {
1205     return __o->fetch_and(__op);
1206 }
1207
1208 template <class _Tp>
1209 inline _LIBCPP_INLINE_VISIBILITY
1210 typename enable_if
1211 <
1212     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1213     _Tp
1214 >::type
1215 atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1216 {
1217     return __o->fetch_and(__op);
1218 }
1219
1220 // atomic_fetch_and_explicit
1221
1222 template <class _Tp>
1223 inline _LIBCPP_INLINE_VISIBILITY
1224 typename enable_if
1225 <
1226     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1227     _Tp
1228 >::type
1229 atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1230 {
1231     return __o->fetch_and(__op, __m);
1232 }
1233
1234 template <class _Tp>
1235 inline _LIBCPP_INLINE_VISIBILITY
1236 typename enable_if
1237 <
1238     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1239     _Tp
1240 >::type
1241 atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1242 {
1243     return __o->fetch_and(__op, __m);
1244 }
1245
1246 // atomic_fetch_or
1247
1248 template <class _Tp>
1249 inline _LIBCPP_INLINE_VISIBILITY
1250 typename enable_if
1251 <
1252     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1253     _Tp
1254 >::type
1255 atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1256 {
1257     return __o->fetch_or(__op);
1258 }
1259
1260 template <class _Tp>
1261 inline _LIBCPP_INLINE_VISIBILITY
1262 typename enable_if
1263 <
1264     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1265     _Tp
1266 >::type
1267 atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1268 {
1269     return __o->fetch_or(__op);
1270 }
1271
1272 // atomic_fetch_or_explicit
1273
1274 template <class _Tp>
1275 inline _LIBCPP_INLINE_VISIBILITY
1276 typename enable_if
1277 <
1278     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1279     _Tp
1280 >::type
1281 atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1282 {
1283     return __o->fetch_or(__op, __m);
1284 }
1285
1286 template <class _Tp>
1287 inline _LIBCPP_INLINE_VISIBILITY
1288 typename enable_if
1289 <
1290     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1291     _Tp
1292 >::type
1293 atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1294 {
1295     return __o->fetch_or(__op, __m);
1296 }
1297
1298 // atomic_fetch_xor
1299
1300 template <class _Tp>
1301 inline _LIBCPP_INLINE_VISIBILITY
1302 typename enable_if
1303 <
1304     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1305     _Tp
1306 >::type
1307 atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1308 {
1309     return __o->fetch_xor(__op);
1310 }
1311
1312 template <class _Tp>
1313 inline _LIBCPP_INLINE_VISIBILITY
1314 typename enable_if
1315 <
1316     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1317     _Tp
1318 >::type
1319 atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1320 {
1321     return __o->fetch_xor(__op);
1322 }
1323
1324 // atomic_fetch_xor_explicit
1325
1326 template <class _Tp>
1327 inline _LIBCPP_INLINE_VISIBILITY
1328 typename enable_if
1329 <
1330     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1331     _Tp
1332 >::type
1333 atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1334 {
1335     return __o->fetch_xor(__op, __m);
1336 }
1337
1338 template <class _Tp>
1339 inline _LIBCPP_INLINE_VISIBILITY
1340 typename enable_if
1341 <
1342     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1343     _Tp
1344 >::type
1345 atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1346 {
1347     return __o->fetch_xor(__op, __m);
1348 }
1349
1350 // flag type and operations
1351
1352 typedef struct atomic_flag
1353 {
1354     _Atomic(bool) __a_;
1355
1356     _LIBCPP_INLINE_VISIBILITY
1357     bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1358         {return __c11_atomic_exchange(&__a_, true, __m);}
1359     _LIBCPP_INLINE_VISIBILITY
1360     bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1361         {return __c11_atomic_exchange(&__a_, true, __m);}
1362     _LIBCPP_INLINE_VISIBILITY
1363     void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1364         {__c11_atomic_store(&__a_, false, __m);}
1365     _LIBCPP_INLINE_VISIBILITY
1366     void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1367         {__c11_atomic_store(&__a_, false, __m);}
1368
1369     _LIBCPP_INLINE_VISIBILITY
1370     atomic_flag() _NOEXCEPT {} // = default;
1371     _LIBCPP_INLINE_VISIBILITY
1372     atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {}
1373
1374 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1375     atomic_flag(const atomic_flag&) = delete;
1376     atomic_flag& operator=(const atomic_flag&) = delete;
1377     atomic_flag& operator=(const atomic_flag&) volatile = delete;
1378 #else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1379 private:
1380     atomic_flag(const atomic_flag&);
1381     atomic_flag& operator=(const atomic_flag&);
1382     atomic_flag& operator=(const atomic_flag&) volatile;
1383 #endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1384 } atomic_flag;
1385
1386 inline _LIBCPP_INLINE_VISIBILITY
1387 bool
1388 atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
1389 {
1390     return __o->test_and_set();
1391 }
1392
1393 inline _LIBCPP_INLINE_VISIBILITY
1394 bool
1395 atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
1396 {
1397     return __o->test_and_set();
1398 }
1399
1400 inline _LIBCPP_INLINE_VISIBILITY
1401 bool
1402 atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
1403 {
1404     return __o->test_and_set(__m);
1405 }
1406
1407 inline _LIBCPP_INLINE_VISIBILITY
1408 bool
1409 atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
1410 {
1411     return __o->test_and_set(__m);
1412 }
1413
1414 inline _LIBCPP_INLINE_VISIBILITY
1415 void
1416 atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
1417 {
1418     __o->clear();
1419 }
1420
1421 inline _LIBCPP_INLINE_VISIBILITY
1422 void
1423 atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
1424 {
1425     __o->clear();
1426 }
1427
1428 inline _LIBCPP_INLINE_VISIBILITY
1429 void
1430 atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
1431 {
1432     __o->clear(__m);
1433 }
1434
1435 inline _LIBCPP_INLINE_VISIBILITY
1436 void
1437 atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
1438 {
1439     __o->clear(__m);
1440 }
1441
1442 // fences
1443
1444 inline _LIBCPP_INLINE_VISIBILITY
1445 void
1446 atomic_thread_fence(memory_order __m) _NOEXCEPT
1447 {
1448     __c11_atomic_thread_fence(__m);
1449 }
1450
1451 inline _LIBCPP_INLINE_VISIBILITY
1452 void
1453 atomic_signal_fence(memory_order __m) _NOEXCEPT
1454 {
1455     __c11_atomic_signal_fence(__m);
1456 }
1457
1458 // Atomics for standard typedef types
1459
1460 typedef atomic<bool>               atomic_bool;
1461 typedef atomic<char>               atomic_char;
1462 typedef atomic<signed char>        atomic_schar;
1463 typedef atomic<unsigned char>      atomic_uchar;
1464 typedef atomic<short>              atomic_short;
1465 typedef atomic<unsigned short>     atomic_ushort;
1466 typedef atomic<int>                atomic_int;
1467 typedef atomic<unsigned int>       atomic_uint;
1468 typedef atomic<long>               atomic_long;
1469 typedef atomic<unsigned long>      atomic_ulong;
1470 typedef atomic<long long>          atomic_llong;
1471 typedef atomic<unsigned long long> atomic_ullong;
1472 typedef atomic<char16_t>           atomic_char16_t;
1473 typedef atomic<char32_t>           atomic_char32_t;
1474 typedef atomic<wchar_t>            atomic_wchar_t;
1475
1476 typedef atomic<int_least8_t>   atomic_int_least8_t;
1477 typedef atomic<uint_least8_t>  atomic_uint_least8_t;
1478 typedef atomic<int_least16_t>  atomic_int_least16_t;
1479 typedef atomic<uint_least16_t> atomic_uint_least16_t;
1480 typedef atomic<int_least32_t>  atomic_int_least32_t;
1481 typedef atomic<uint_least32_t> atomic_uint_least32_t;
1482 typedef atomic<int_least64_t>  atomic_int_least64_t;
1483 typedef atomic<uint_least64_t> atomic_uint_least64_t;
1484
1485 typedef atomic<int_fast8_t>   atomic_int_fast8_t;
1486 typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
1487 typedef atomic<int_fast16_t>  atomic_int_fast16_t;
1488 typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1489 typedef atomic<int_fast32_t>  atomic_int_fast32_t;
1490 typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1491 typedef atomic<int_fast64_t>  atomic_int_fast64_t;
1492 typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1493
1494 typedef atomic<intptr_t>  atomic_intptr_t;
1495 typedef atomic<uintptr_t> atomic_uintptr_t;
1496 typedef atomic<size_t>    atomic_size_t;
1497 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1498 typedef atomic<intmax_t>  atomic_intmax_t;
1499 typedef atomic<uintmax_t> atomic_uintmax_t;
1500
1501 #define ATOMIC_FLAG_INIT {false}
1502 #define ATOMIC_VAR_INIT(__v) {__v}
1503
1504 // lock-free property
1505
1506 #define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
1507 #define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
1508 #define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1509 #define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1510 #define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1511 #define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
1512 #define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
1513 #define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
1514 #define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
1515 #define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
1516
1517 #endif  //  !__has_feature(cxx_atomic)
1518
1519 _LIBCPP_END_NAMESPACE_STD
1520
1521 #endif  // _LIBCPP_ATOMIC