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