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