xref: /llvm-project-15.0.7/libcxx/include/atomic (revision 2946cd70)
1// -*- C++ -*-
2//===--------------------------- atomic -----------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_ATOMIC
11#define _LIBCPP_ATOMIC
12
13/*
14    atomic synopsis
15
16namespace std
17{
18
19// feature test macro
20
21#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10
22
23// order and consistency
24
25typedef enum memory_order
26{
27    memory_order_relaxed,
28    memory_order_consume,  // load-consume
29    memory_order_acquire,  // load-acquire
30    memory_order_release,  // store-release
31    memory_order_acq_rel,  // store-release load-acquire
32    memory_order_seq_cst   // store-release load-acquire
33} memory_order;
34
35template <class T> T kill_dependency(T y) noexcept;
36
37// lock-free property
38
39#define ATOMIC_BOOL_LOCK_FREE unspecified
40#define ATOMIC_CHAR_LOCK_FREE unspecified
41#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
42#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
43#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
44#define ATOMIC_SHORT_LOCK_FREE unspecified
45#define ATOMIC_INT_LOCK_FREE unspecified
46#define ATOMIC_LONG_LOCK_FREE unspecified
47#define ATOMIC_LLONG_LOCK_FREE unspecified
48#define ATOMIC_POINTER_LOCK_FREE unspecified
49
50// flag type and operations
51
52typedef struct atomic_flag
53{
54    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
55    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
56    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
57    void clear(memory_order m = memory_order_seq_cst) noexcept;
58    atomic_flag()  noexcept = default;
59    atomic_flag(const atomic_flag&) = delete;
60    atomic_flag& operator=(const atomic_flag&) = delete;
61    atomic_flag& operator=(const atomic_flag&) volatile = delete;
62} atomic_flag;
63
64bool
65    atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
66
67bool
68    atomic_flag_test_and_set(atomic_flag* obj) noexcept;
69
70bool
71    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
72                                      memory_order m) noexcept;
73
74bool
75    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
76
77void
78    atomic_flag_clear(volatile atomic_flag* obj) noexcept;
79
80void
81    atomic_flag_clear(atomic_flag* obj) noexcept;
82
83void
84    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
85
86void
87    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
88
89#define ATOMIC_FLAG_INIT see below
90#define ATOMIC_VAR_INIT(value) see below
91
92template <class T>
93struct atomic
94{
95    static constexpr bool is_always_lock_free;
96    bool is_lock_free() const volatile noexcept;
97    bool is_lock_free() const noexcept;
98    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
99    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
100    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
101    T load(memory_order m = memory_order_seq_cst) const noexcept;
102    operator T() const volatile noexcept;
103    operator T() const noexcept;
104    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
105    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
106    bool compare_exchange_weak(T& expc, T desr,
107                               memory_order s, memory_order f) volatile noexcept;
108    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
109    bool compare_exchange_strong(T& expc, T desr,
110                                 memory_order s, memory_order f) volatile noexcept;
111    bool compare_exchange_strong(T& expc, T desr,
112                                 memory_order s, memory_order f) noexcept;
113    bool compare_exchange_weak(T& expc, T desr,
114                               memory_order m = memory_order_seq_cst) volatile noexcept;
115    bool compare_exchange_weak(T& expc, T desr,
116                               memory_order m = memory_order_seq_cst) noexcept;
117    bool compare_exchange_strong(T& expc, T desr,
118                                memory_order m = memory_order_seq_cst) volatile noexcept;
119    bool compare_exchange_strong(T& expc, T desr,
120                                 memory_order m = memory_order_seq_cst) noexcept;
121
122    atomic() noexcept = default;
123    constexpr atomic(T desr) noexcept;
124    atomic(const atomic&) = delete;
125    atomic& operator=(const atomic&) = delete;
126    atomic& operator=(const atomic&) volatile = delete;
127    T operator=(T) volatile noexcept;
128    T operator=(T) noexcept;
129};
130
131template <>
132struct atomic<integral>
133{
134    static constexpr bool is_always_lock_free;
135    bool is_lock_free() const volatile noexcept;
136    bool is_lock_free() const noexcept;
137    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
138    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
139    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
140    integral load(memory_order m = memory_order_seq_cst) const noexcept;
141    operator integral() const volatile noexcept;
142    operator integral() const noexcept;
143    integral exchange(integral desr,
144                      memory_order m = memory_order_seq_cst) volatile noexcept;
145    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
146    bool compare_exchange_weak(integral& expc, integral desr,
147                               memory_order s, memory_order f) volatile noexcept;
148    bool compare_exchange_weak(integral& expc, integral desr,
149                               memory_order s, memory_order f) noexcept;
150    bool compare_exchange_strong(integral& expc, integral desr,
151                                 memory_order s, memory_order f) volatile noexcept;
152    bool compare_exchange_strong(integral& expc, integral desr,
153                                 memory_order s, memory_order f) noexcept;
154    bool compare_exchange_weak(integral& expc, integral desr,
155                               memory_order m = memory_order_seq_cst) volatile noexcept;
156    bool compare_exchange_weak(integral& expc, integral desr,
157                               memory_order m = memory_order_seq_cst) noexcept;
158    bool compare_exchange_strong(integral& expc, integral desr,
159                                memory_order m = memory_order_seq_cst) volatile noexcept;
160    bool compare_exchange_strong(integral& expc, integral desr,
161                                 memory_order m = memory_order_seq_cst) noexcept;
162
163    integral
164        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
165    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
166    integral
167        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
168    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
169    integral
170        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
171    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
172    integral
173        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
174    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
175    integral
176        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
177    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
178
179    atomic() noexcept = default;
180    constexpr atomic(integral desr) noexcept;
181    atomic(const atomic&) = delete;
182    atomic& operator=(const atomic&) = delete;
183    atomic& operator=(const atomic&) volatile = delete;
184    integral operator=(integral desr) volatile noexcept;
185    integral operator=(integral desr) noexcept;
186
187    integral operator++(int) volatile noexcept;
188    integral operator++(int) noexcept;
189    integral operator--(int) volatile noexcept;
190    integral operator--(int) noexcept;
191    integral operator++() volatile noexcept;
192    integral operator++() noexcept;
193    integral operator--() volatile noexcept;
194    integral operator--() noexcept;
195    integral operator+=(integral op) volatile noexcept;
196    integral operator+=(integral op) noexcept;
197    integral operator-=(integral op) volatile noexcept;
198    integral operator-=(integral op) noexcept;
199    integral operator&=(integral op) volatile noexcept;
200    integral operator&=(integral op) noexcept;
201    integral operator|=(integral op) volatile noexcept;
202    integral operator|=(integral op) noexcept;
203    integral operator^=(integral op) volatile noexcept;
204    integral operator^=(integral op) noexcept;
205};
206
207template <class T>
208struct atomic<T*>
209{
210    static constexpr bool is_always_lock_free;
211    bool is_lock_free() const volatile noexcept;
212    bool is_lock_free() const noexcept;
213    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
214    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
215    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
216    T* load(memory_order m = memory_order_seq_cst) const noexcept;
217    operator T*() const volatile noexcept;
218    operator T*() const noexcept;
219    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
220    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
221    bool compare_exchange_weak(T*& expc, T* desr,
222                               memory_order s, memory_order f) volatile noexcept;
223    bool compare_exchange_weak(T*& expc, T* desr,
224                               memory_order s, memory_order f) noexcept;
225    bool compare_exchange_strong(T*& expc, T* desr,
226                                 memory_order s, memory_order f) volatile noexcept;
227    bool compare_exchange_strong(T*& expc, T* desr,
228                                 memory_order s, memory_order f) noexcept;
229    bool compare_exchange_weak(T*& expc, T* desr,
230                               memory_order m = memory_order_seq_cst) volatile noexcept;
231    bool compare_exchange_weak(T*& expc, T* desr,
232                               memory_order m = memory_order_seq_cst) noexcept;
233    bool compare_exchange_strong(T*& expc, T* desr,
234                                memory_order m = memory_order_seq_cst) volatile noexcept;
235    bool compare_exchange_strong(T*& expc, T* desr,
236                                 memory_order m = memory_order_seq_cst) noexcept;
237    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
238    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
239    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
240    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
241
242    atomic() noexcept = default;
243    constexpr atomic(T* desr) noexcept;
244    atomic(const atomic&) = delete;
245    atomic& operator=(const atomic&) = delete;
246    atomic& operator=(const atomic&) volatile = delete;
247
248    T* operator=(T*) volatile noexcept;
249    T* operator=(T*) noexcept;
250    T* operator++(int) volatile noexcept;
251    T* operator++(int) noexcept;
252    T* operator--(int) volatile noexcept;
253    T* operator--(int) noexcept;
254    T* operator++() volatile noexcept;
255    T* operator++() noexcept;
256    T* operator--() volatile noexcept;
257    T* operator--() noexcept;
258    T* operator+=(ptrdiff_t op) volatile noexcept;
259    T* operator+=(ptrdiff_t op) noexcept;
260    T* operator-=(ptrdiff_t op) volatile noexcept;
261    T* operator-=(ptrdiff_t op) noexcept;
262};
263
264
265template <class T>
266    bool
267    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
268
269template <class T>
270    bool
271    atomic_is_lock_free(const atomic<T>* obj) noexcept;
272
273template <class T>
274    void
275    atomic_init(volatile atomic<T>* obj, T desr) noexcept;
276
277template <class T>
278    void
279    atomic_init(atomic<T>* obj, T desr) noexcept;
280
281template <class T>
282    void
283    atomic_store(volatile atomic<T>* obj, T desr) noexcept;
284
285template <class T>
286    void
287    atomic_store(atomic<T>* obj, T desr) noexcept;
288
289template <class T>
290    void
291    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
292
293template <class T>
294    void
295    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
296
297template <class T>
298    T
299    atomic_load(const volatile atomic<T>* obj) noexcept;
300
301template <class T>
302    T
303    atomic_load(const atomic<T>* obj) noexcept;
304
305template <class T>
306    T
307    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
308
309template <class T>
310    T
311    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
312
313template <class T>
314    T
315    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
316
317template <class T>
318    T
319    atomic_exchange(atomic<T>* obj, T desr) noexcept;
320
321template <class T>
322    T
323    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
324
325template <class T>
326    T
327    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
328
329template <class T>
330    bool
331    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
332
333template <class T>
334    bool
335    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
336
337template <class T>
338    bool
339    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
340
341template <class T>
342    bool
343    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
344
345template <class T>
346    bool
347    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
348                                          T desr,
349                                          memory_order s, memory_order f) noexcept;
350
351template <class T>
352    bool
353    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
354                                          memory_order s, memory_order f) noexcept;
355
356template <class T>
357    bool
358    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
359                                            T* expc, T desr,
360                                            memory_order s, memory_order f) noexcept;
361
362template <class T>
363    bool
364    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
365                                            T desr,
366                                            memory_order s, memory_order f) noexcept;
367
368template <class Integral>
369    Integral
370    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
371
372template <class Integral>
373    Integral
374    atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
375
376template <class Integral>
377    Integral
378    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
379                              memory_order m) noexcept;
380template <class Integral>
381    Integral
382    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
383                              memory_order m) noexcept;
384template <class Integral>
385    Integral
386    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
387
388template <class Integral>
389    Integral
390    atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
391
392template <class Integral>
393    Integral
394    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
395                              memory_order m) noexcept;
396template <class Integral>
397    Integral
398    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
399                              memory_order m) noexcept;
400template <class Integral>
401    Integral
402    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
403
404template <class Integral>
405    Integral
406    atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
407
408template <class Integral>
409    Integral
410    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
411                              memory_order m) noexcept;
412template <class Integral>
413    Integral
414    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
415                              memory_order m) noexcept;
416template <class Integral>
417    Integral
418    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
419
420template <class Integral>
421    Integral
422    atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
423
424template <class Integral>
425    Integral
426    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
427                             memory_order m) noexcept;
428template <class Integral>
429    Integral
430    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
431                             memory_order m) noexcept;
432template <class Integral>
433    Integral
434    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
435
436template <class Integral>
437    Integral
438    atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
439
440template <class Integral>
441    Integral
442    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
443                              memory_order m) noexcept;
444template <class Integral>
445    Integral
446    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
447                              memory_order m) noexcept;
448
449template <class T>
450    T*
451    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
452
453template <class T>
454    T*
455    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
456
457template <class T>
458    T*
459    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
460                              memory_order m) noexcept;
461template <class T>
462    T*
463    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
464
465template <class T>
466    T*
467    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
468
469template <class T>
470    T*
471    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
472
473template <class T>
474    T*
475    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
476                              memory_order m) noexcept;
477template <class T>
478    T*
479    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
480
481// Atomics for standard typedef types
482
483typedef atomic<bool>               atomic_bool;
484typedef atomic<char>               atomic_char;
485typedef atomic<signed char>        atomic_schar;
486typedef atomic<unsigned char>      atomic_uchar;
487typedef atomic<short>              atomic_short;
488typedef atomic<unsigned short>     atomic_ushort;
489typedef atomic<int>                atomic_int;
490typedef atomic<unsigned int>       atomic_uint;
491typedef atomic<long>               atomic_long;
492typedef atomic<unsigned long>      atomic_ulong;
493typedef atomic<long long>          atomic_llong;
494typedef atomic<unsigned long long> atomic_ullong;
495typedef atomic<char16_t>           atomic_char16_t;
496typedef atomic<char32_t>           atomic_char32_t;
497typedef atomic<wchar_t>            atomic_wchar_t;
498
499typedef atomic<int_least8_t>   atomic_int_least8_t;
500typedef atomic<uint_least8_t>  atomic_uint_least8_t;
501typedef atomic<int_least16_t>  atomic_int_least16_t;
502typedef atomic<uint_least16_t> atomic_uint_least16_t;
503typedef atomic<int_least32_t>  atomic_int_least32_t;
504typedef atomic<uint_least32_t> atomic_uint_least32_t;
505typedef atomic<int_least64_t>  atomic_int_least64_t;
506typedef atomic<uint_least64_t> atomic_uint_least64_t;
507
508typedef atomic<int_fast8_t>   atomic_int_fast8_t;
509typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
510typedef atomic<int_fast16_t>  atomic_int_fast16_t;
511typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
512typedef atomic<int_fast32_t>  atomic_int_fast32_t;
513typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
514typedef atomic<int_fast64_t>  atomic_int_fast64_t;
515typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
516
517typedef atomic<int8_t>   atomic_int8_t;
518typedef atomic<uint8_t>  atomic_uint8_t;
519typedef atomic<int16_t>  atomic_int16_t;
520typedef atomic<uint16_t> atomic_uint16_t;
521typedef atomic<int32_t>  atomic_int32_t;
522typedef atomic<uint32_t> atomic_uint32_t;
523typedef atomic<int64_t>  atomic_int64_t;
524typedef atomic<uint64_t> atomic_uint64_t;
525
526typedef atomic<intptr_t>  atomic_intptr_t;
527typedef atomic<uintptr_t> atomic_uintptr_t;
528typedef atomic<size_t>    atomic_size_t;
529typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
530typedef atomic<intmax_t>  atomic_intmax_t;
531typedef atomic<uintmax_t> atomic_uintmax_t;
532
533// fences
534
535void atomic_thread_fence(memory_order m) noexcept;
536void atomic_signal_fence(memory_order m) noexcept;
537
538}  // std
539
540*/
541
542#include <__config>
543#include <cstddef>
544#include <cstdint>
545#include <type_traits>
546#include <version>
547
548#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
549#pragma GCC system_header
550#endif
551
552#ifdef _LIBCPP_HAS_NO_THREADS
553#error <atomic> is not supported on this single threaded system
554#endif
555#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
556#error <atomic> is not implemented
557#endif
558#ifdef kill_dependency
559#error C++ standard library is incompatible with <stdatomic.h>
560#endif
561
562#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
563  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
564                           __m == memory_order_acquire || \
565                           __m == memory_order_acq_rel,   \
566                        "memory order argument to atomic operation is invalid")
567
568#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
569  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
570                           __m == memory_order_acq_rel,   \
571                        "memory order argument to atomic operation is invalid")
572
573#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
574  _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
575                           __f == memory_order_acq_rel,   \
576                        "memory order argument to atomic operation is invalid")
577
578_LIBCPP_BEGIN_NAMESPACE_STD
579
580typedef enum memory_order
581{
582    memory_order_relaxed, memory_order_consume, memory_order_acquire,
583    memory_order_release, memory_order_acq_rel, memory_order_seq_cst
584} memory_order;
585
586#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
587namespace __gcc_atomic {
588template <typename _Tp>
589struct __gcc_atomic_t {
590
591#if _GNUC_VER >= 501
592    static_assert(is_trivially_copyable<_Tp>::value,
593      "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
594#endif
595
596  _LIBCPP_INLINE_VISIBILITY
597#ifndef _LIBCPP_CXX03_LANG
598    __gcc_atomic_t() _NOEXCEPT = default;
599#else
600    __gcc_atomic_t() _NOEXCEPT : __a_value() {}
601#endif // _LIBCPP_CXX03_LANG
602  _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT
603    : __a_value(value) {}
604  _Tp __a_value;
605};
606#define _Atomic(x) __gcc_atomic::__gcc_atomic_t<x>
607
608template <typename _Tp> _Tp __create();
609
610template <typename _Tp, typename _Td>
611typename enable_if<sizeof(_Tp()->__a_value = __create<_Td>()), char>::type
612    __test_atomic_assignable(int);
613template <typename _Tp, typename _Up>
614__two __test_atomic_assignable(...);
615
616template <typename _Tp, typename _Td>
617struct __can_assign {
618  static const bool value =
619      sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char);
620};
621
622static inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
623  // Avoid switch statement to make this a constexpr.
624  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
625         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
626          (__order == memory_order_release ? __ATOMIC_RELEASE:
627           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
628            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
629              __ATOMIC_CONSUME))));
630}
631
632static inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
633  // Avoid switch statement to make this a constexpr.
634  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
635         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
636          (__order == memory_order_release ? __ATOMIC_RELAXED:
637           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
638            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
639              __ATOMIC_CONSUME))));
640}
641
642} // namespace __gcc_atomic
643
644template <typename _Tp>
645static inline
646typename enable_if<
647    __gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value>::type
648__c11_atomic_init(volatile _Atomic(_Tp)* __a,  _Tp __val) {
649  __a->__a_value = __val;
650}
651
652template <typename _Tp>
653static inline
654typename enable_if<
655    !__gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value &&
656     __gcc_atomic::__can_assign<         _Atomic(_Tp)*, _Tp>::value>::type
657__c11_atomic_init(volatile _Atomic(_Tp)* __a,  _Tp __val) {
658  // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
659  // the default operator= in an object is not volatile, a byte-by-byte copy
660  // is required.
661  volatile char* to = reinterpret_cast<volatile char*>(&__a->__a_value);
662  volatile char* end = to + sizeof(_Tp);
663  char* from = reinterpret_cast<char*>(&__val);
664  while (to != end) {
665    *to++ = *from++;
666  }
667}
668
669template <typename _Tp>
670static inline void __c11_atomic_init(_Atomic(_Tp)* __a,  _Tp __val) {
671  __a->__a_value = __val;
672}
673
674static inline void __c11_atomic_thread_fence(memory_order __order) {
675  __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order));
676}
677
678static inline void __c11_atomic_signal_fence(memory_order __order) {
679  __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order));
680}
681
682template <typename _Tp>
683static inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a,  _Tp __val,
684                                      memory_order __order) {
685  return __atomic_store(&__a->__a_value, &__val,
686                        __gcc_atomic::__to_gcc_order(__order));
687}
688
689template <typename _Tp>
690static inline void __c11_atomic_store(_Atomic(_Tp)* __a,  _Tp __val,
691                                      memory_order __order) {
692  __atomic_store(&__a->__a_value, &__val,
693                 __gcc_atomic::__to_gcc_order(__order));
694}
695
696template <typename _Tp>
697static inline _Tp __c11_atomic_load(const volatile _Atomic(_Tp)* __a,
698                                    memory_order __order) {
699  _Tp __ret;
700  __atomic_load(&__a->__a_value, &__ret,
701                __gcc_atomic::__to_gcc_order(__order));
702  return __ret;
703}
704
705template <typename _Tp>
706static inline _Tp __c11_atomic_load(const _Atomic(_Tp)* __a, memory_order __order) {
707  _Tp __ret;
708  __atomic_load(&__a->__a_value, &__ret,
709                __gcc_atomic::__to_gcc_order(__order));
710  return __ret;
711}
712
713template <typename _Tp>
714static inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a,
715                                        _Tp __value, memory_order __order) {
716  _Tp __ret;
717  __atomic_exchange(&__a->__a_value, &__value, &__ret,
718                    __gcc_atomic::__to_gcc_order(__order));
719  return __ret;
720}
721
722template <typename _Tp>
723static inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value,
724                                        memory_order __order) {
725  _Tp __ret;
726  __atomic_exchange(&__a->__a_value, &__value, &__ret,
727                    __gcc_atomic::__to_gcc_order(__order));
728  return __ret;
729}
730
731template <typename _Tp>
732static inline bool __c11_atomic_compare_exchange_strong(
733    volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
734    memory_order __success, memory_order __failure) {
735  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
736                                   false,
737                                   __gcc_atomic::__to_gcc_order(__success),
738                                   __gcc_atomic::__to_gcc_failure_order(__failure));
739}
740
741template <typename _Tp>
742static inline bool __c11_atomic_compare_exchange_strong(
743    _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
744    memory_order __failure) {
745  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
746                                   false,
747                                   __gcc_atomic::__to_gcc_order(__success),
748                                   __gcc_atomic::__to_gcc_failure_order(__failure));
749}
750
751template <typename _Tp>
752static inline bool __c11_atomic_compare_exchange_weak(
753    volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
754    memory_order __success, memory_order __failure) {
755  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
756                                   true,
757                                   __gcc_atomic::__to_gcc_order(__success),
758                                   __gcc_atomic::__to_gcc_failure_order(__failure));
759}
760
761template <typename _Tp>
762static inline bool __c11_atomic_compare_exchange_weak(
763    _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
764    memory_order __failure) {
765  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
766                                   true,
767                                   __gcc_atomic::__to_gcc_order(__success),
768                                   __gcc_atomic::__to_gcc_failure_order(__failure));
769}
770
771template <typename _Tp>
772struct __skip_amt { enum {value = 1}; };
773
774template <typename _Tp>
775struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
776
777// FIXME: Haven't figured out what the spec says about using arrays with
778// atomic_fetch_add. Force a failure rather than creating bad behavior.
779template <typename _Tp>
780struct __skip_amt<_Tp[]> { };
781template <typename _Tp, int n>
782struct __skip_amt<_Tp[n]> { };
783
784template <typename _Tp, typename _Td>
785static inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a,
786                                         _Td __delta, memory_order __order) {
787  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
788                            __gcc_atomic::__to_gcc_order(__order));
789}
790
791template <typename _Tp, typename _Td>
792static inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta,
793                                         memory_order __order) {
794  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
795                            __gcc_atomic::__to_gcc_order(__order));
796}
797
798template <typename _Tp, typename _Td>
799static inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a,
800                                         _Td __delta, memory_order __order) {
801  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
802                            __gcc_atomic::__to_gcc_order(__order));
803}
804
805template <typename _Tp, typename _Td>
806static inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta,
807                                         memory_order __order) {
808  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
809                            __gcc_atomic::__to_gcc_order(__order));
810}
811
812template <typename _Tp>
813static inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a,
814                                         _Tp __pattern, memory_order __order) {
815  return __atomic_fetch_and(&__a->__a_value, __pattern,
816                            __gcc_atomic::__to_gcc_order(__order));
817}
818
819template <typename _Tp>
820static inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a,
821                                         _Tp __pattern, memory_order __order) {
822  return __atomic_fetch_and(&__a->__a_value, __pattern,
823                            __gcc_atomic::__to_gcc_order(__order));
824}
825
826template <typename _Tp>
827static inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a,
828                                        _Tp __pattern, memory_order __order) {
829  return __atomic_fetch_or(&__a->__a_value, __pattern,
830                           __gcc_atomic::__to_gcc_order(__order));
831}
832
833template <typename _Tp>
834static inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern,
835                                        memory_order __order) {
836  return __atomic_fetch_or(&__a->__a_value, __pattern,
837                           __gcc_atomic::__to_gcc_order(__order));
838}
839
840template <typename _Tp>
841static inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a,
842                                         _Tp __pattern, memory_order __order) {
843  return __atomic_fetch_xor(&__a->__a_value, __pattern,
844                            __gcc_atomic::__to_gcc_order(__order));
845}
846
847template <typename _Tp>
848static inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern,
849                                         memory_order __order) {
850  return __atomic_fetch_xor(&__a->__a_value, __pattern,
851                            __gcc_atomic::__to_gcc_order(__order));
852}
853#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP
854
855template <class _Tp>
856inline _LIBCPP_INLINE_VISIBILITY
857_Tp
858kill_dependency(_Tp __y) _NOEXCEPT
859{
860    return __y;
861}
862
863#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
864# define ATOMIC_BOOL_LOCK_FREE      __CLANG_ATOMIC_BOOL_LOCK_FREE
865# define ATOMIC_CHAR_LOCK_FREE      __CLANG_ATOMIC_CHAR_LOCK_FREE
866# define ATOMIC_CHAR16_T_LOCK_FREE  __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
867# define ATOMIC_CHAR32_T_LOCK_FREE  __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
868# define ATOMIC_WCHAR_T_LOCK_FREE   __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
869# define ATOMIC_SHORT_LOCK_FREE     __CLANG_ATOMIC_SHORT_LOCK_FREE
870# define ATOMIC_INT_LOCK_FREE       __CLANG_ATOMIC_INT_LOCK_FREE
871# define ATOMIC_LONG_LOCK_FREE      __CLANG_ATOMIC_LONG_LOCK_FREE
872# define ATOMIC_LLONG_LOCK_FREE     __CLANG_ATOMIC_LLONG_LOCK_FREE
873# define ATOMIC_POINTER_LOCK_FREE   __CLANG_ATOMIC_POINTER_LOCK_FREE
874#else
875# define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
876# define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
877# define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
878# define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
879# define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
880# define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
881# define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
882# define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
883# define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
884# define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
885#endif
886
887// general atomic<T>
888
889template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
890struct __atomic_base  // false
891{
892    mutable _Atomic(_Tp) __a_;
893
894#if defined(__cpp_lib_atomic_is_always_lock_free)
895  static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
896#endif
897
898    _LIBCPP_INLINE_VISIBILITY
899    bool is_lock_free() const volatile _NOEXCEPT
900    {
901#if defined(_LIBCPP_HAS_C_ATOMIC_IMP)
902    return __c11_atomic_is_lock_free(sizeof(_Tp));
903#else
904    return __atomic_is_lock_free(sizeof(_Tp), 0);
905#endif
906    }
907    _LIBCPP_INLINE_VISIBILITY
908    bool is_lock_free() const _NOEXCEPT
909        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
910    _LIBCPP_INLINE_VISIBILITY
911    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
912      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
913        {__c11_atomic_store(&__a_, __d, __m);}
914    _LIBCPP_INLINE_VISIBILITY
915    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
916      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
917        {__c11_atomic_store(&__a_, __d, __m);}
918    _LIBCPP_INLINE_VISIBILITY
919    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
920      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
921        {return __c11_atomic_load(&__a_, __m);}
922    _LIBCPP_INLINE_VISIBILITY
923    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
924      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
925        {return __c11_atomic_load(&__a_, __m);}
926    _LIBCPP_INLINE_VISIBILITY
927    operator _Tp() const volatile _NOEXCEPT {return load();}
928    _LIBCPP_INLINE_VISIBILITY
929    operator _Tp() const _NOEXCEPT          {return load();}
930    _LIBCPP_INLINE_VISIBILITY
931    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
932        {return __c11_atomic_exchange(&__a_, __d, __m);}
933    _LIBCPP_INLINE_VISIBILITY
934    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
935        {return __c11_atomic_exchange(&__a_, __d, __m);}
936    _LIBCPP_INLINE_VISIBILITY
937    bool compare_exchange_weak(_Tp& __e, _Tp __d,
938                               memory_order __s, memory_order __f) volatile _NOEXCEPT
939      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
940        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
941    _LIBCPP_INLINE_VISIBILITY
942    bool compare_exchange_weak(_Tp& __e, _Tp __d,
943                               memory_order __s, memory_order __f) _NOEXCEPT
944      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
945        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
946    _LIBCPP_INLINE_VISIBILITY
947    bool compare_exchange_strong(_Tp& __e, _Tp __d,
948                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
949      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
950        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
951    _LIBCPP_INLINE_VISIBILITY
952    bool compare_exchange_strong(_Tp& __e, _Tp __d,
953                                 memory_order __s, memory_order __f) _NOEXCEPT
954      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
955        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
956    _LIBCPP_INLINE_VISIBILITY
957    bool compare_exchange_weak(_Tp& __e, _Tp __d,
958                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
959        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
960    _LIBCPP_INLINE_VISIBILITY
961    bool compare_exchange_weak(_Tp& __e, _Tp __d,
962                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
963        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
964    _LIBCPP_INLINE_VISIBILITY
965    bool compare_exchange_strong(_Tp& __e, _Tp __d,
966                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
967        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
968    _LIBCPP_INLINE_VISIBILITY
969    bool compare_exchange_strong(_Tp& __e, _Tp __d,
970                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
971        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
972
973    _LIBCPP_INLINE_VISIBILITY
974#ifndef _LIBCPP_CXX03_LANG
975    __atomic_base() _NOEXCEPT = default;
976#else
977    __atomic_base() _NOEXCEPT : __a_() {}
978#endif // _LIBCPP_CXX03_LANG
979
980    _LIBCPP_INLINE_VISIBILITY
981    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
982#ifndef _LIBCPP_CXX03_LANG
983    __atomic_base(const __atomic_base&) = delete;
984    __atomic_base& operator=(const __atomic_base&) = delete;
985    __atomic_base& operator=(const __atomic_base&) volatile = delete;
986#else
987private:
988    __atomic_base(const __atomic_base&);
989    __atomic_base& operator=(const __atomic_base&);
990    __atomic_base& operator=(const __atomic_base&) volatile;
991#endif
992};
993
994#if defined(__cpp_lib_atomic_is_always_lock_free)
995template <class _Tp, bool __b>
996_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
997#endif
998
999// atomic<Integral>
1000
1001template <class _Tp>
1002struct __atomic_base<_Tp, true>
1003    : public __atomic_base<_Tp, false>
1004{
1005    typedef __atomic_base<_Tp, false> __base;
1006    _LIBCPP_INLINE_VISIBILITY
1007    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
1008    _LIBCPP_INLINE_VISIBILITY
1009    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
1010
1011    _LIBCPP_INLINE_VISIBILITY
1012    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1013        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
1014    _LIBCPP_INLINE_VISIBILITY
1015    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1016        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
1017    _LIBCPP_INLINE_VISIBILITY
1018    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1019        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
1020    _LIBCPP_INLINE_VISIBILITY
1021    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1022        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
1023    _LIBCPP_INLINE_VISIBILITY
1024    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1025        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
1026    _LIBCPP_INLINE_VISIBILITY
1027    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1028        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
1029    _LIBCPP_INLINE_VISIBILITY
1030    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1031        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
1032    _LIBCPP_INLINE_VISIBILITY
1033    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1034        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
1035    _LIBCPP_INLINE_VISIBILITY
1036    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1037        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
1038    _LIBCPP_INLINE_VISIBILITY
1039    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1040        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
1041
1042    _LIBCPP_INLINE_VISIBILITY
1043    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
1044    _LIBCPP_INLINE_VISIBILITY
1045    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
1046    _LIBCPP_INLINE_VISIBILITY
1047    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
1048    _LIBCPP_INLINE_VISIBILITY
1049    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
1050    _LIBCPP_INLINE_VISIBILITY
1051    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
1052    _LIBCPP_INLINE_VISIBILITY
1053    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
1054    _LIBCPP_INLINE_VISIBILITY
1055    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
1056    _LIBCPP_INLINE_VISIBILITY
1057    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
1058    _LIBCPP_INLINE_VISIBILITY
1059    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1060    _LIBCPP_INLINE_VISIBILITY
1061    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
1062    _LIBCPP_INLINE_VISIBILITY
1063    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1064    _LIBCPP_INLINE_VISIBILITY
1065    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1066    _LIBCPP_INLINE_VISIBILITY
1067    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
1068    _LIBCPP_INLINE_VISIBILITY
1069    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
1070    _LIBCPP_INLINE_VISIBILITY
1071    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
1072    _LIBCPP_INLINE_VISIBILITY
1073    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
1074    _LIBCPP_INLINE_VISIBILITY
1075    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
1076    _LIBCPP_INLINE_VISIBILITY
1077    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
1078};
1079
1080// atomic<T>
1081
1082template <class _Tp>
1083struct atomic
1084    : public __atomic_base<_Tp>
1085{
1086    typedef __atomic_base<_Tp> __base;
1087    _LIBCPP_INLINE_VISIBILITY
1088    atomic() _NOEXCEPT _LIBCPP_DEFAULT
1089    _LIBCPP_INLINE_VISIBILITY
1090    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
1091
1092    _LIBCPP_INLINE_VISIBILITY
1093    _Tp operator=(_Tp __d) volatile _NOEXCEPT
1094        {__base::store(__d); return __d;}
1095    _LIBCPP_INLINE_VISIBILITY
1096    _Tp operator=(_Tp __d) _NOEXCEPT
1097        {__base::store(__d); return __d;}
1098};
1099
1100// atomic<T*>
1101
1102template <class _Tp>
1103struct atomic<_Tp*>
1104    : public __atomic_base<_Tp*>
1105{
1106    typedef __atomic_base<_Tp*> __base;
1107    _LIBCPP_INLINE_VISIBILITY
1108    atomic() _NOEXCEPT _LIBCPP_DEFAULT
1109    _LIBCPP_INLINE_VISIBILITY
1110    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
1111
1112    _LIBCPP_INLINE_VISIBILITY
1113    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
1114        {__base::store(__d); return __d;}
1115    _LIBCPP_INLINE_VISIBILITY
1116    _Tp* operator=(_Tp* __d) _NOEXCEPT
1117        {__base::store(__d); return __d;}
1118
1119    _LIBCPP_INLINE_VISIBILITY
1120    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
1121                                                                        volatile _NOEXCEPT
1122        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
1123    _LIBCPP_INLINE_VISIBILITY
1124    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1125        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
1126    _LIBCPP_INLINE_VISIBILITY
1127    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
1128                                                                        volatile _NOEXCEPT
1129        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
1130    _LIBCPP_INLINE_VISIBILITY
1131    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1132        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
1133
1134    _LIBCPP_INLINE_VISIBILITY
1135    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
1136    _LIBCPP_INLINE_VISIBILITY
1137    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
1138    _LIBCPP_INLINE_VISIBILITY
1139    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
1140    _LIBCPP_INLINE_VISIBILITY
1141    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
1142    _LIBCPP_INLINE_VISIBILITY
1143    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
1144    _LIBCPP_INLINE_VISIBILITY
1145    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
1146    _LIBCPP_INLINE_VISIBILITY
1147    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
1148    _LIBCPP_INLINE_VISIBILITY
1149    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
1150    _LIBCPP_INLINE_VISIBILITY
1151    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1152    _LIBCPP_INLINE_VISIBILITY
1153    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
1154    _LIBCPP_INLINE_VISIBILITY
1155    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1156    _LIBCPP_INLINE_VISIBILITY
1157    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1158};
1159
1160// atomic_is_lock_free
1161
1162template <class _Tp>
1163inline _LIBCPP_INLINE_VISIBILITY
1164bool
1165atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
1166{
1167    return __o->is_lock_free();
1168}
1169
1170template <class _Tp>
1171inline _LIBCPP_INLINE_VISIBILITY
1172bool
1173atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
1174{
1175    return __o->is_lock_free();
1176}
1177
1178// atomic_init
1179
1180template <class _Tp>
1181inline _LIBCPP_INLINE_VISIBILITY
1182void
1183atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1184{
1185    __c11_atomic_init(&__o->__a_, __d);
1186}
1187
1188template <class _Tp>
1189inline _LIBCPP_INLINE_VISIBILITY
1190void
1191atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1192{
1193    __c11_atomic_init(&__o->__a_, __d);
1194}
1195
1196// atomic_store
1197
1198template <class _Tp>
1199inline _LIBCPP_INLINE_VISIBILITY
1200void
1201atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1202{
1203    __o->store(__d);
1204}
1205
1206template <class _Tp>
1207inline _LIBCPP_INLINE_VISIBILITY
1208void
1209atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1210{
1211    __o->store(__d);
1212}
1213
1214// atomic_store_explicit
1215
1216template <class _Tp>
1217inline _LIBCPP_INLINE_VISIBILITY
1218void
1219atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1220  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1221{
1222    __o->store(__d, __m);
1223}
1224
1225template <class _Tp>
1226inline _LIBCPP_INLINE_VISIBILITY
1227void
1228atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1229  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1230{
1231    __o->store(__d, __m);
1232}
1233
1234// atomic_load
1235
1236template <class _Tp>
1237inline _LIBCPP_INLINE_VISIBILITY
1238_Tp
1239atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
1240{
1241    return __o->load();
1242}
1243
1244template <class _Tp>
1245inline _LIBCPP_INLINE_VISIBILITY
1246_Tp
1247atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
1248{
1249    return __o->load();
1250}
1251
1252// atomic_load_explicit
1253
1254template <class _Tp>
1255inline _LIBCPP_INLINE_VISIBILITY
1256_Tp
1257atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1258  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1259{
1260    return __o->load(__m);
1261}
1262
1263template <class _Tp>
1264inline _LIBCPP_INLINE_VISIBILITY
1265_Tp
1266atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1267  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1268{
1269    return __o->load(__m);
1270}
1271
1272// atomic_exchange
1273
1274template <class _Tp>
1275inline _LIBCPP_INLINE_VISIBILITY
1276_Tp
1277atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1278{
1279    return __o->exchange(__d);
1280}
1281
1282template <class _Tp>
1283inline _LIBCPP_INLINE_VISIBILITY
1284_Tp
1285atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1286{
1287    return __o->exchange(__d);
1288}
1289
1290// atomic_exchange_explicit
1291
1292template <class _Tp>
1293inline _LIBCPP_INLINE_VISIBILITY
1294_Tp
1295atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1296{
1297    return __o->exchange(__d, __m);
1298}
1299
1300template <class _Tp>
1301inline _LIBCPP_INLINE_VISIBILITY
1302_Tp
1303atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1304{
1305    return __o->exchange(__d, __m);
1306}
1307
1308// atomic_compare_exchange_weak
1309
1310template <class _Tp>
1311inline _LIBCPP_INLINE_VISIBILITY
1312bool
1313atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1314{
1315    return __o->compare_exchange_weak(*__e, __d);
1316}
1317
1318template <class _Tp>
1319inline _LIBCPP_INLINE_VISIBILITY
1320bool
1321atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1322{
1323    return __o->compare_exchange_weak(*__e, __d);
1324}
1325
1326// atomic_compare_exchange_strong
1327
1328template <class _Tp>
1329inline _LIBCPP_INLINE_VISIBILITY
1330bool
1331atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1332{
1333    return __o->compare_exchange_strong(*__e, __d);
1334}
1335
1336template <class _Tp>
1337inline _LIBCPP_INLINE_VISIBILITY
1338bool
1339atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1340{
1341    return __o->compare_exchange_strong(*__e, __d);
1342}
1343
1344// atomic_compare_exchange_weak_explicit
1345
1346template <class _Tp>
1347inline _LIBCPP_INLINE_VISIBILITY
1348bool
1349atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
1350                                      _Tp __d,
1351                                      memory_order __s, memory_order __f) _NOEXCEPT
1352  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1353{
1354    return __o->compare_exchange_weak(*__e, __d, __s, __f);
1355}
1356
1357template <class _Tp>
1358inline _LIBCPP_INLINE_VISIBILITY
1359bool
1360atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
1361                                      memory_order __s, memory_order __f) _NOEXCEPT
1362  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1363{
1364    return __o->compare_exchange_weak(*__e, __d, __s, __f);
1365}
1366
1367// atomic_compare_exchange_strong_explicit
1368
1369template <class _Tp>
1370inline _LIBCPP_INLINE_VISIBILITY
1371bool
1372atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1373                                        _Tp* __e, _Tp __d,
1374                                        memory_order __s, memory_order __f) _NOEXCEPT
1375  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1376{
1377    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1378}
1379
1380template <class _Tp>
1381inline _LIBCPP_INLINE_VISIBILITY
1382bool
1383atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1384                                        _Tp __d,
1385                                        memory_order __s, memory_order __f) _NOEXCEPT
1386  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1387{
1388    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1389}
1390
1391// atomic_fetch_add
1392
1393template <class _Tp>
1394inline _LIBCPP_INLINE_VISIBILITY
1395typename enable_if
1396<
1397    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1398    _Tp
1399>::type
1400atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1401{
1402    return __o->fetch_add(__op);
1403}
1404
1405template <class _Tp>
1406inline _LIBCPP_INLINE_VISIBILITY
1407typename enable_if
1408<
1409    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1410    _Tp
1411>::type
1412atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1413{
1414    return __o->fetch_add(__op);
1415}
1416
1417template <class _Tp>
1418inline _LIBCPP_INLINE_VISIBILITY
1419_Tp*
1420atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1421{
1422    return __o->fetch_add(__op);
1423}
1424
1425template <class _Tp>
1426inline _LIBCPP_INLINE_VISIBILITY
1427_Tp*
1428atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1429{
1430    return __o->fetch_add(__op);
1431}
1432
1433// atomic_fetch_add_explicit
1434
1435template <class _Tp>
1436inline _LIBCPP_INLINE_VISIBILITY
1437typename enable_if
1438<
1439    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1440    _Tp
1441>::type
1442atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1443{
1444    return __o->fetch_add(__op, __m);
1445}
1446
1447template <class _Tp>
1448inline _LIBCPP_INLINE_VISIBILITY
1449typename enable_if
1450<
1451    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1452    _Tp
1453>::type
1454atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1455{
1456    return __o->fetch_add(__op, __m);
1457}
1458
1459template <class _Tp>
1460inline _LIBCPP_INLINE_VISIBILITY
1461_Tp*
1462atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1463                          memory_order __m) _NOEXCEPT
1464{
1465    return __o->fetch_add(__op, __m);
1466}
1467
1468template <class _Tp>
1469inline _LIBCPP_INLINE_VISIBILITY
1470_Tp*
1471atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
1472{
1473    return __o->fetch_add(__op, __m);
1474}
1475
1476// atomic_fetch_sub
1477
1478template <class _Tp>
1479inline _LIBCPP_INLINE_VISIBILITY
1480typename enable_if
1481<
1482    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1483    _Tp
1484>::type
1485atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1486{
1487    return __o->fetch_sub(__op);
1488}
1489
1490template <class _Tp>
1491inline _LIBCPP_INLINE_VISIBILITY
1492typename enable_if
1493<
1494    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1495    _Tp
1496>::type
1497atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1498{
1499    return __o->fetch_sub(__op);
1500}
1501
1502template <class _Tp>
1503inline _LIBCPP_INLINE_VISIBILITY
1504_Tp*
1505atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1506{
1507    return __o->fetch_sub(__op);
1508}
1509
1510template <class _Tp>
1511inline _LIBCPP_INLINE_VISIBILITY
1512_Tp*
1513atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1514{
1515    return __o->fetch_sub(__op);
1516}
1517
1518// atomic_fetch_sub_explicit
1519
1520template <class _Tp>
1521inline _LIBCPP_INLINE_VISIBILITY
1522typename enable_if
1523<
1524    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1525    _Tp
1526>::type
1527atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1528{
1529    return __o->fetch_sub(__op, __m);
1530}
1531
1532template <class _Tp>
1533inline _LIBCPP_INLINE_VISIBILITY
1534typename enable_if
1535<
1536    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1537    _Tp
1538>::type
1539atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1540{
1541    return __o->fetch_sub(__op, __m);
1542}
1543
1544template <class _Tp>
1545inline _LIBCPP_INLINE_VISIBILITY
1546_Tp*
1547atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1548                          memory_order __m) _NOEXCEPT
1549{
1550    return __o->fetch_sub(__op, __m);
1551}
1552
1553template <class _Tp>
1554inline _LIBCPP_INLINE_VISIBILITY
1555_Tp*
1556atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
1557{
1558    return __o->fetch_sub(__op, __m);
1559}
1560
1561// atomic_fetch_and
1562
1563template <class _Tp>
1564inline _LIBCPP_INLINE_VISIBILITY
1565typename enable_if
1566<
1567    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1568    _Tp
1569>::type
1570atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1571{
1572    return __o->fetch_and(__op);
1573}
1574
1575template <class _Tp>
1576inline _LIBCPP_INLINE_VISIBILITY
1577typename enable_if
1578<
1579    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1580    _Tp
1581>::type
1582atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1583{
1584    return __o->fetch_and(__op);
1585}
1586
1587// atomic_fetch_and_explicit
1588
1589template <class _Tp>
1590inline _LIBCPP_INLINE_VISIBILITY
1591typename enable_if
1592<
1593    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1594    _Tp
1595>::type
1596atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1597{
1598    return __o->fetch_and(__op, __m);
1599}
1600
1601template <class _Tp>
1602inline _LIBCPP_INLINE_VISIBILITY
1603typename enable_if
1604<
1605    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1606    _Tp
1607>::type
1608atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1609{
1610    return __o->fetch_and(__op, __m);
1611}
1612
1613// atomic_fetch_or
1614
1615template <class _Tp>
1616inline _LIBCPP_INLINE_VISIBILITY
1617typename enable_if
1618<
1619    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1620    _Tp
1621>::type
1622atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1623{
1624    return __o->fetch_or(__op);
1625}
1626
1627template <class _Tp>
1628inline _LIBCPP_INLINE_VISIBILITY
1629typename enable_if
1630<
1631    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1632    _Tp
1633>::type
1634atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1635{
1636    return __o->fetch_or(__op);
1637}
1638
1639// atomic_fetch_or_explicit
1640
1641template <class _Tp>
1642inline _LIBCPP_INLINE_VISIBILITY
1643typename enable_if
1644<
1645    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1646    _Tp
1647>::type
1648atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1649{
1650    return __o->fetch_or(__op, __m);
1651}
1652
1653template <class _Tp>
1654inline _LIBCPP_INLINE_VISIBILITY
1655typename enable_if
1656<
1657    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1658    _Tp
1659>::type
1660atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1661{
1662    return __o->fetch_or(__op, __m);
1663}
1664
1665// atomic_fetch_xor
1666
1667template <class _Tp>
1668inline _LIBCPP_INLINE_VISIBILITY
1669typename enable_if
1670<
1671    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1672    _Tp
1673>::type
1674atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1675{
1676    return __o->fetch_xor(__op);
1677}
1678
1679template <class _Tp>
1680inline _LIBCPP_INLINE_VISIBILITY
1681typename enable_if
1682<
1683    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1684    _Tp
1685>::type
1686atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1687{
1688    return __o->fetch_xor(__op);
1689}
1690
1691// atomic_fetch_xor_explicit
1692
1693template <class _Tp>
1694inline _LIBCPP_INLINE_VISIBILITY
1695typename enable_if
1696<
1697    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1698    _Tp
1699>::type
1700atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1701{
1702    return __o->fetch_xor(__op, __m);
1703}
1704
1705template <class _Tp>
1706inline _LIBCPP_INLINE_VISIBILITY
1707typename enable_if
1708<
1709    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1710    _Tp
1711>::type
1712atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1713{
1714    return __o->fetch_xor(__op, __m);
1715}
1716
1717// flag type and operations
1718
1719typedef struct atomic_flag
1720{
1721    _Atomic(bool) __a_;
1722
1723    _LIBCPP_INLINE_VISIBILITY
1724    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1725        {return __c11_atomic_exchange(&__a_, true, __m);}
1726    _LIBCPP_INLINE_VISIBILITY
1727    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1728        {return __c11_atomic_exchange(&__a_, true, __m);}
1729    _LIBCPP_INLINE_VISIBILITY
1730    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1731        {__c11_atomic_store(&__a_, false, __m);}
1732    _LIBCPP_INLINE_VISIBILITY
1733    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1734        {__c11_atomic_store(&__a_, false, __m);}
1735
1736    _LIBCPP_INLINE_VISIBILITY
1737#ifndef _LIBCPP_CXX03_LANG
1738    atomic_flag() _NOEXCEPT = default;
1739#else
1740    atomic_flag() _NOEXCEPT : __a_() {}
1741#endif // _LIBCPP_CXX03_LANG
1742
1743    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1744    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
1745
1746#ifndef _LIBCPP_CXX03_LANG
1747    atomic_flag(const atomic_flag&) = delete;
1748    atomic_flag& operator=(const atomic_flag&) = delete;
1749    atomic_flag& operator=(const atomic_flag&) volatile = delete;
1750#else
1751private:
1752    atomic_flag(const atomic_flag&);
1753    atomic_flag& operator=(const atomic_flag&);
1754    atomic_flag& operator=(const atomic_flag&) volatile;
1755#endif
1756} atomic_flag;
1757
1758inline _LIBCPP_INLINE_VISIBILITY
1759bool
1760atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
1761{
1762    return __o->test_and_set();
1763}
1764
1765inline _LIBCPP_INLINE_VISIBILITY
1766bool
1767atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
1768{
1769    return __o->test_and_set();
1770}
1771
1772inline _LIBCPP_INLINE_VISIBILITY
1773bool
1774atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
1775{
1776    return __o->test_and_set(__m);
1777}
1778
1779inline _LIBCPP_INLINE_VISIBILITY
1780bool
1781atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
1782{
1783    return __o->test_and_set(__m);
1784}
1785
1786inline _LIBCPP_INLINE_VISIBILITY
1787void
1788atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
1789{
1790    __o->clear();
1791}
1792
1793inline _LIBCPP_INLINE_VISIBILITY
1794void
1795atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
1796{
1797    __o->clear();
1798}
1799
1800inline _LIBCPP_INLINE_VISIBILITY
1801void
1802atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
1803{
1804    __o->clear(__m);
1805}
1806
1807inline _LIBCPP_INLINE_VISIBILITY
1808void
1809atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
1810{
1811    __o->clear(__m);
1812}
1813
1814// fences
1815
1816inline _LIBCPP_INLINE_VISIBILITY
1817void
1818atomic_thread_fence(memory_order __m) _NOEXCEPT
1819{
1820    __c11_atomic_thread_fence(__m);
1821}
1822
1823inline _LIBCPP_INLINE_VISIBILITY
1824void
1825atomic_signal_fence(memory_order __m) _NOEXCEPT
1826{
1827    __c11_atomic_signal_fence(__m);
1828}
1829
1830// Atomics for standard typedef types
1831
1832typedef atomic<bool>               atomic_bool;
1833typedef atomic<char>               atomic_char;
1834typedef atomic<signed char>        atomic_schar;
1835typedef atomic<unsigned char>      atomic_uchar;
1836typedef atomic<short>              atomic_short;
1837typedef atomic<unsigned short>     atomic_ushort;
1838typedef atomic<int>                atomic_int;
1839typedef atomic<unsigned int>       atomic_uint;
1840typedef atomic<long>               atomic_long;
1841typedef atomic<unsigned long>      atomic_ulong;
1842typedef atomic<long long>          atomic_llong;
1843typedef atomic<unsigned long long> atomic_ullong;
1844typedef atomic<char16_t>           atomic_char16_t;
1845typedef atomic<char32_t>           atomic_char32_t;
1846typedef atomic<wchar_t>            atomic_wchar_t;
1847
1848typedef atomic<int_least8_t>   atomic_int_least8_t;
1849typedef atomic<uint_least8_t>  atomic_uint_least8_t;
1850typedef atomic<int_least16_t>  atomic_int_least16_t;
1851typedef atomic<uint_least16_t> atomic_uint_least16_t;
1852typedef atomic<int_least32_t>  atomic_int_least32_t;
1853typedef atomic<uint_least32_t> atomic_uint_least32_t;
1854typedef atomic<int_least64_t>  atomic_int_least64_t;
1855typedef atomic<uint_least64_t> atomic_uint_least64_t;
1856
1857typedef atomic<int_fast8_t>   atomic_int_fast8_t;
1858typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
1859typedef atomic<int_fast16_t>  atomic_int_fast16_t;
1860typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1861typedef atomic<int_fast32_t>  atomic_int_fast32_t;
1862typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1863typedef atomic<int_fast64_t>  atomic_int_fast64_t;
1864typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1865
1866typedef atomic< int8_t>  atomic_int8_t;
1867typedef atomic<uint8_t>  atomic_uint8_t;
1868typedef atomic< int16_t> atomic_int16_t;
1869typedef atomic<uint16_t> atomic_uint16_t;
1870typedef atomic< int32_t> atomic_int32_t;
1871typedef atomic<uint32_t> atomic_uint32_t;
1872typedef atomic< int64_t> atomic_int64_t;
1873typedef atomic<uint64_t> atomic_uint64_t;
1874
1875typedef atomic<intptr_t>  atomic_intptr_t;
1876typedef atomic<uintptr_t> atomic_uintptr_t;
1877typedef atomic<size_t>    atomic_size_t;
1878typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1879typedef atomic<intmax_t>  atomic_intmax_t;
1880typedef atomic<uintmax_t> atomic_uintmax_t;
1881
1882#define ATOMIC_FLAG_INIT {false}
1883#define ATOMIC_VAR_INIT(__v) {__v}
1884
1885_LIBCPP_END_NAMESPACE_STD
1886
1887#endif  // _LIBCPP_ATOMIC
1888