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