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