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