atomic revision 288943
10SN/A// -*- C++ -*-
216989Srriggs//===--------------------------- atomic -----------------------------------===//
30SN/A//
40SN/A//                     The LLVM Compiler Infrastructure
50SN/A//
60SN/A// This file is distributed under the University of Illinois Open Source
72362SN/A// License. See LICENSE.TXT for details.
80SN/A//
92362SN/A//===----------------------------------------------------------------------===//
100SN/A
110SN/A#ifndef _LIBCPP_ATOMIC
120SN/A#define _LIBCPP_ATOMIC
130SN/A
140SN/A/*
150SN/A    atomic synopsis
160SN/A
170SN/Anamespace std
180SN/A{
190SN/A
200SN/A// order and consistency
212362SN/A
222362SN/Atypedef enum memory_order
232362SN/A{
240SN/A    memory_order_relaxed,
250SN/A    memory_order_consume,  // load-consume
260SN/A    memory_order_acquire,  // load-acquire
270SN/A    memory_order_release,  // store-release
28471SN/A    memory_order_acq_rel,  // store-release load-acquire
290SN/A    memory_order_seq_cst   // store-release load-acquire
300SN/A} memory_order;
310SN/A
320SN/Atemplate <class T> T kill_dependency(T y) noexcept;
330SN/A
340SN/A// lock-free property
3512546Savstepan
360SN/A#define ATOMIC_BOOL_LOCK_FREE unspecified
370SN/A#define ATOMIC_CHAR_LOCK_FREE unspecified
380SN/A#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
390SN/A#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
400SN/A#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
410SN/A#define ATOMIC_SHORT_LOCK_FREE unspecified
420SN/A#define ATOMIC_INT_LOCK_FREE unspecified
4312546Savstepan#define ATOMIC_LONG_LOCK_FREE unspecified
440SN/A#define ATOMIC_LLONG_LOCK_FREE unspecified
450SN/A#define ATOMIC_POINTER_LOCK_FREE unspecified
460SN/A
470SN/A// flag type and operations
480SN/A
490SN/Atypedef struct atomic_flag
5012546Savstepan{
510SN/A    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
520SN/A    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
5312546Savstepan    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
540SN/A    void clear(memory_order m = memory_order_seq_cst) noexcept;
5512546Savstepan    atomic_flag()  noexcept = default;
560SN/A    atomic_flag(const atomic_flag&) = delete;
570SN/A    atomic_flag& operator=(const atomic_flag&) = delete;
580SN/A    atomic_flag& operator=(const atomic_flag&) volatile = delete;
5912546Savstepan} atomic_flag;
600SN/A
610SN/Abool
6212546Savstepan    atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
630SN/A
640SN/Abool
650SN/A    atomic_flag_test_and_set(atomic_flag* obj) noexcept;
660SN/A
670SN/Abool
680SN/A    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
690SN/A                                      memory_order m) noexcept;
700SN/A
710SN/Abool
720SN/A    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
730SN/A
740SN/Avoid
750SN/A    atomic_flag_clear(volatile atomic_flag* obj) noexcept;
760SN/A
770SN/Avoid
780SN/A    atomic_flag_clear(atomic_flag* obj) noexcept;
790SN/A
800SN/Avoid
810SN/A    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
820SN/A
830SN/Avoid
840SN/A    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
850SN/A
860SN/A#define ATOMIC_FLAG_INIT see below
870SN/A#define ATOMIC_VAR_INIT(value) see below
880SN/A
890SN/Atemplate <class T>
900SN/Astruct atomic
910SN/A{
920SN/A    bool is_lock_free() const volatile noexcept;
930SN/A    bool is_lock_free() const noexcept;
940SN/A    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
950SN/A    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
96479SN/A    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
970SN/A    T load(memory_order m = memory_order_seq_cst) const noexcept;
980SN/A    operator T() const volatile noexcept;
990SN/A    operator T() const noexcept;
1000SN/A    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
101479SN/A    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
1020SN/A    bool compare_exchange_weak(T& expc, T desr,
1030SN/A                               memory_order s, memory_order f) volatile noexcept;
1040SN/A    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
1050SN/A    bool compare_exchange_strong(T& expc, T desr,
1060SN/A                                 memory_order s, memory_order f) volatile noexcept;
1070SN/A    bool compare_exchange_strong(T& expc, T desr,
1080SN/A                                 memory_order s, memory_order f) noexcept;
1090SN/A    bool compare_exchange_weak(T& expc, T desr,
110479SN/A                               memory_order m = memory_order_seq_cst) volatile noexcept;
11116989Srriggs    bool compare_exchange_weak(T& expc, T desr,
1120SN/A                               memory_order m = memory_order_seq_cst) noexcept;
1130SN/A    bool compare_exchange_strong(T& expc, T desr,
1140SN/A                                memory_order m = memory_order_seq_cst) volatile noexcept;
1150SN/A    bool compare_exchange_strong(T& expc, T desr,
1160SN/A                                 memory_order m = memory_order_seq_cst) noexcept;
1170SN/A
1180SN/A    atomic() noexcept = default;
1190SN/A    constexpr atomic(T desr) noexcept;
1200SN/A    atomic(const atomic&) = delete;
121471SN/A    atomic& operator=(const atomic&) = delete;
1220SN/A    atomic& operator=(const atomic&) volatile = delete;
12312745Smartin    T operator=(T) volatile noexcept;
124471SN/A    T operator=(T) noexcept;
125471SN/A};
1260SN/A
1270SN/Atemplate <>
1280SN/Astruct atomic<integral>
1290SN/A{
1300SN/A    bool is_lock_free() const volatile noexcept;
1310SN/A    bool is_lock_free() const noexcept;
1320SN/A    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
1330SN/A    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1340SN/A    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
1350SN/A    integral load(memory_order m = memory_order_seq_cst) const noexcept;
1360SN/A    operator integral() const volatile noexcept;
1370SN/A    operator integral() const noexcept;
1380SN/A    integral exchange(integral desr,
1390SN/A                      memory_order m = memory_order_seq_cst) volatile noexcept;
1400SN/A    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1410SN/A    bool compare_exchange_weak(integral& expc, integral desr,
1420SN/A                               memory_order s, memory_order f) volatile noexcept;
1430SN/A    bool compare_exchange_weak(integral& expc, integral desr,
1440SN/A                               memory_order s, memory_order f) noexcept;
1450SN/A    bool compare_exchange_strong(integral& expc, integral desr,
1460SN/A                                 memory_order s, memory_order f) volatile noexcept;
1470SN/A    bool compare_exchange_strong(integral& expc, integral desr,
1480SN/A                                 memory_order s, memory_order f) noexcept;
1490SN/A    bool compare_exchange_weak(integral& expc, integral desr,
1500SN/A                               memory_order m = memory_order_seq_cst) volatile noexcept;
1510SN/A    bool compare_exchange_weak(integral& expc, integral desr,
1520SN/A                               memory_order m = memory_order_seq_cst) noexcept;
1530SN/A    bool compare_exchange_strong(integral& expc, integral desr,
1540SN/A                                memory_order m = memory_order_seq_cst) volatile noexcept;
1550SN/A    bool compare_exchange_strong(integral& expc, integral desr,
1560SN/A                                 memory_order m = memory_order_seq_cst) noexcept;
1570SN/A
1580SN/A    integral
1590SN/A        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1600SN/A    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
1610SN/A    integral
1620SN/A        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1630SN/A    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
1640SN/A    integral
1650SN/A        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1660SN/A    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
1670SN/A    integral
1680SN/A        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1690SN/A    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
1700SN/A    integral
1710SN/A        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1720SN/A    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
1730SN/A
1740SN/A    atomic() noexcept = default;
1750SN/A    constexpr atomic(integral desr) noexcept;
1760SN/A    atomic(const atomic&) = delete;
1770SN/A    atomic& operator=(const atomic&) = delete;
1780SN/A    atomic& operator=(const atomic&) volatile = delete;
1790SN/A    integral operator=(integral desr) volatile noexcept;
1800SN/A    integral operator=(integral desr) noexcept;
1810SN/A
1820SN/A    integral operator++(int) volatile noexcept;
1830SN/A    integral operator++(int) noexcept;
1840SN/A    integral operator--(int) volatile noexcept;
18512546Savstepan    integral operator--(int) noexcept;
18612546Savstepan    integral operator++() volatile noexcept;
1870SN/A    integral operator++() noexcept;
1880SN/A    integral operator--() volatile noexcept;
1890SN/A    integral operator--() noexcept;
1900SN/A    integral operator+=(integral op) volatile noexcept;
1910SN/A    integral operator+=(integral op) noexcept;
1920SN/A    integral operator-=(integral op) volatile noexcept;
1930SN/A    integral operator-=(integral op) noexcept;
1940SN/A    integral operator&=(integral op) volatile noexcept;
1950SN/A    integral operator&=(integral op) noexcept;
1960SN/A    integral operator|=(integral op) volatile noexcept;
1970SN/A    integral operator|=(integral op) noexcept;
1980SN/A    integral operator^=(integral op) volatile noexcept;
1990SN/A    integral operator^=(integral op) noexcept;
2000SN/A};
2010SN/A
2020SN/Atemplate <class T>
20312546Savstepanstruct atomic<T*>
2040SN/A{
2050SN/A    bool is_lock_free() const volatile noexcept;
2060SN/A    bool is_lock_free() const noexcept;
2070SN/A    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
2080SN/A    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2090SN/A    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
2100SN/A    T* load(memory_order m = memory_order_seq_cst) const noexcept;
2110SN/A    operator T*() const volatile noexcept;
2120SN/A    operator T*() const noexcept;
2130SN/A    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
2140SN/A    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2150SN/A    bool compare_exchange_weak(T*& expc, T* desr,
2160SN/A                               memory_order s, memory_order f) volatile noexcept;
2170SN/A    bool compare_exchange_weak(T*& expc, T* desr,
2180SN/A                               memory_order s, memory_order f) noexcept;
2190SN/A    bool compare_exchange_strong(T*& expc, T* desr,
2200SN/A                                 memory_order s, memory_order f) volatile noexcept;
2210SN/A    bool compare_exchange_strong(T*& expc, T* desr,
2220SN/A                                 memory_order s, memory_order f) noexcept;
22312546Savstepan    bool compare_exchange_weak(T*& expc, T* desr,
2240SN/A                               memory_order m = memory_order_seq_cst) volatile noexcept;
2250SN/A    bool compare_exchange_weak(T*& expc, T* desr,
2260SN/A                               memory_order m = memory_order_seq_cst) noexcept;
2270SN/A    bool compare_exchange_strong(T*& expc, T* desr,
2280SN/A                                memory_order m = memory_order_seq_cst) volatile noexcept;
2290SN/A    bool compare_exchange_strong(T*& expc, T* desr,
2300SN/A                                 memory_order m = memory_order_seq_cst) noexcept;
2310SN/A    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
2320SN/A    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2330SN/A    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
2340SN/A    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2350SN/A
2360SN/A    atomic() noexcept = default;
2370SN/A    constexpr atomic(T* desr) noexcept;
2380SN/A    atomic(const atomic&) = delete;
2390SN/A    atomic& operator=(const atomic&) = delete;
2400SN/A    atomic& operator=(const atomic&) volatile = delete;
2410SN/A
2420SN/A    T* operator=(T*) volatile noexcept;
2430SN/A    T* operator=(T*) noexcept;
2440SN/A    T* operator++(int) volatile noexcept;
2450SN/A    T* operator++(int) noexcept;
2460SN/A    T* operator--(int) volatile noexcept;
2470SN/A    T* operator--(int) noexcept;
2480SN/A    T* operator++() volatile noexcept;
2490SN/A    T* operator++() noexcept;
2500SN/A    T* operator--() volatile noexcept;
2510SN/A    T* operator--() noexcept;
2520SN/A    T* operator+=(ptrdiff_t op) volatile noexcept;
2530SN/A    T* operator+=(ptrdiff_t op) noexcept;
2540SN/A    T* operator-=(ptrdiff_t op) volatile noexcept;
2550SN/A    T* operator-=(ptrdiff_t op) noexcept;
2560SN/A};
2570SN/A
2580SN/A
2590SN/Atemplate <class T>
2600SN/A    bool
2610SN/A    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
2620SN/A
26312546Savstepantemplate <class T>
2640SN/A    bool
2650SN/A    atomic_is_lock_free(const atomic<T>* obj) noexcept;
2660SN/A
2670SN/Atemplate <class T>
2680SN/A    void
2690SN/A    atomic_init(volatile atomic<T>* obj, T desr) noexcept;
2700SN/A
2710SN/Atemplate <class T>
2720SN/A    void
2730SN/A    atomic_init(atomic<T>* obj, T desr) noexcept;
2740SN/A
2750SN/Atemplate <class T>
2760SN/A    void
2770SN/A    atomic_store(volatile atomic<T>* obj, T desr) noexcept;
2780SN/A
2790SN/Atemplate <class T>
2800SN/A    void
2810SN/A    atomic_store(atomic<T>* obj, T desr) noexcept;
2820SN/A
2830SN/Atemplate <class T>
2840SN/A    void
2850SN/A    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
2860SN/A
2870SN/Atemplate <class T>
2880SN/A    void
2890SN/A    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
2900SN/A
2910SN/Atemplate <class T>
2920SN/A    T
2930SN/A    atomic_load(const volatile atomic<T>* obj) noexcept;
2940SN/A
2950SN/Atemplate <class T>
2960SN/A    T
2970SN/A    atomic_load(const atomic<T>* obj) noexcept;
2980SN/A
2990SN/Atemplate <class T>
3000SN/A    T
3010SN/A    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
30212546Savstepan
3030SN/Atemplate <class T>
3040SN/A    T
3050SN/A    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
3060SN/A
3070SN/Atemplate <class T>
3080SN/A    T
3090SN/A    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
3100SN/A
3110SN/Atemplate <class T>
3120SN/A    T
3130SN/A    atomic_exchange(atomic<T>* obj, T desr) noexcept;
3140SN/A
3150SN/Atemplate <class T>
3160SN/A    T
3170SN/A    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
3180SN/A
3190SN/Atemplate <class T>
3200SN/A    T
3210SN/A    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
3220SN/A
3230SN/Atemplate <class T>
3240SN/A    bool
3250SN/A    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
3260SN/A
3270SN/Atemplate <class T>
3280SN/A    bool
3290SN/A    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
3300SN/A
3310SN/Atemplate <class T>
3320SN/A    bool
3330SN/A    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
3340SN/A
3350SN/Atemplate <class T>
3360SN/A    bool
3370SN/A    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
3380SN/A
3390SN/Atemplate <class T>
3400SN/A    bool
3410SN/A    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
3420SN/A                                          T desr,
34312546Savstepan                                          memory_order s, memory_order f) noexcept;
3440SN/A
3450SN/Atemplate <class T>
3460SN/A    bool
3470SN/A    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
3480SN/A                                          memory_order s, memory_order f) noexcept;
3490SN/A
3500SN/Atemplate <class T>
3510SN/A    bool
3520SN/A    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
3530SN/A                                            T* expc, T desr,
3540SN/A                                            memory_order s, memory_order f) noexcept;
3550SN/A
3560SN/Atemplate <class T>
3570SN/A    bool
3580SN/A    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
3590SN/A                                            T desr,
3600SN/A                                            memory_order s, memory_order f) noexcept;
3610SN/A
3620SN/Atemplate <class Integral>
3630SN/A    Integral
3640SN/A    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
3650SN/A
3660SN/Atemplate <class Integral>
3670SN/A    Integral
3680SN/A    atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
3690SN/A
3700SN/Atemplate <class Integral>
3710SN/A    Integral
3720SN/A    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
3730SN/A                              memory_order m) noexcept;
3740SN/Atemplate <class Integral>
3750SN/A    Integral
3760SN/A    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
3770SN/A                              memory_order m) noexcept;
3780SN/Atemplate <class Integral>
3790SN/A    Integral
3800SN/A    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
3810SN/A
38212546Savstepantemplate <class Integral>
3830SN/A    Integral
3840SN/A    atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
3850SN/A
3860SN/Atemplate <class Integral>
3870SN/A    Integral
3880SN/A    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
3890SN/A                              memory_order m) noexcept;
3900SN/Atemplate <class Integral>
391479SN/A    Integral
392479SN/A    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
393479SN/A                              memory_order m) noexcept;
394479SN/Atemplate <class Integral>
395479SN/A    Integral
3960SN/A    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
3970SN/A
3980SN/Atemplate <class Integral>
3990SN/A    Integral
4000SN/A    atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
4010SN/A
4020SN/Atemplate <class Integral>
4030SN/A    Integral
4040SN/A    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
4050SN/A                              memory_order m) noexcept;
4060SN/Atemplate <class Integral>
4070SN/A    Integral
4080SN/A    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
4090SN/A                              memory_order m) noexcept;
4100SN/Atemplate <class Integral>
4110SN/A    Integral
4120SN/A    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
4130SN/A
4140SN/Atemplate <class Integral>
4150SN/A    Integral
4160SN/A    atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
4170SN/A
4180SN/Atemplate <class Integral>
4190SN/A    Integral
4200SN/A    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
4210SN/A                             memory_order m) noexcept;
4220SN/Atemplate <class Integral>
4230SN/A    Integral
4240SN/A    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
4250SN/A                             memory_order m) noexcept;
4260SN/Atemplate <class Integral>
4270SN/A    Integral
4280SN/A    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
4290SN/A
4300SN/Atemplate <class Integral>
4310SN/A    Integral
4320SN/A    atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
4330SN/A
4340SN/Atemplate <class Integral>
4350SN/A    Integral
4360SN/A    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
4370SN/A                              memory_order m) noexcept;
4380SN/Atemplate <class Integral>
4390SN/A    Integral
4400SN/A    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
4410SN/A                              memory_order m) noexcept;
4420SN/A
4430SN/Atemplate <class T>
4440SN/A    T*
4450SN/A    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
4460SN/A
4470SN/Atemplate <class T>
4480SN/A    T*
4490SN/A    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
4500SN/A
45113217Ssmarkstemplate <class T>
4520SN/A    T*
4530SN/A    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
4540SN/A                              memory_order m) noexcept;
4550SN/Atemplate <class T>
4560SN/A    T*
4570SN/A    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
4580SN/A
4590SN/Atemplate <class T>
4600SN/A    T*
4610SN/A    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
4620SN/A
4630SN/Atemplate <class T>
4640SN/A    T*
4650SN/A    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
4660SN/A
4670SN/Atemplate <class T>
4680SN/A    T*
4690SN/A    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
4700SN/A                              memory_order m) noexcept;
4710SN/Atemplate <class T>
4720SN/A    T*
4730SN/A    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
4740SN/A
4750SN/A// Atomics for standard typedef types
4760SN/A
4770SN/Atypedef atomic<bool>               atomic_bool;
4780SN/Atypedef atomic<char>               atomic_char;
4790SN/Atypedef atomic<signed char>        atomic_schar;
4800SN/Atypedef atomic<unsigned char>      atomic_uchar;
4810SN/Atypedef atomic<short>              atomic_short;
4820SN/Atypedef atomic<unsigned short>     atomic_ushort;
4830SN/Atypedef atomic<int>                atomic_int;
4840SN/Atypedef atomic<unsigned int>       atomic_uint;
4850SN/Atypedef atomic<long>               atomic_long;
4860SN/Atypedef atomic<unsigned long>      atomic_ulong;
4870SN/Atypedef atomic<long long>          atomic_llong;
4880SN/Atypedef atomic<unsigned long long> atomic_ullong;
4890SN/Atypedef atomic<char16_t>           atomic_char16_t;
4900SN/Atypedef atomic<char32_t>           atomic_char32_t;
4910SN/Atypedef atomic<wchar_t>            atomic_wchar_t;
4920SN/A
4930SN/Atypedef atomic<int_least8_t>   atomic_int_least8_t;
4940SN/Atypedef atomic<uint_least8_t>  atomic_uint_least8_t;
4950SN/Atypedef atomic<int_least16_t>  atomic_int_least16_t;
4960SN/Atypedef atomic<uint_least16_t> atomic_uint_least16_t;
4970SN/Atypedef atomic<int_least32_t>  atomic_int_least32_t;
4980SN/Atypedef atomic<uint_least32_t> atomic_uint_least32_t;
4990SN/Atypedef atomic<int_least64_t>  atomic_int_least64_t;
5000SN/Atypedef atomic<uint_least64_t> atomic_uint_least64_t;
5010SN/A
5020SN/Atypedef atomic<int_fast8_t>   atomic_int_fast8_t;
5030SN/Atypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
5040SN/Atypedef atomic<int_fast16_t>  atomic_int_fast16_t;
5050SN/Atypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
5060SN/Atypedef atomic<int_fast32_t>  atomic_int_fast32_t;
5070SN/Atypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
5080SN/Atypedef atomic<int_fast64_t>  atomic_int_fast64_t;
5090SN/Atypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
5100SN/A
5110SN/Atypedef atomic<intptr_t>  atomic_intptr_t;
5120SN/Atypedef atomic<uintptr_t> atomic_uintptr_t;
5130SN/Atypedef atomic<size_t>    atomic_size_t;
5140SN/Atypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
5150SN/Atypedef atomic<intmax_t>  atomic_intmax_t;
5160SN/Atypedef atomic<uintmax_t> atomic_uintmax_t;
5170SN/A
5180SN/A// fences
5190SN/A
5200SN/Avoid atomic_thread_fence(memory_order m) noexcept;
5210SN/Avoid atomic_signal_fence(memory_order m) noexcept;
5220SN/A
5230SN/A}  // std
5240SN/A
5250SN/A*/
5260SN/A
5270SN/A#include <__config>
5280SN/A#include <cstddef>
5290SN/A#include <cstdint>
5300SN/A#include <type_traits>
5310SN/A
5320SN/A#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5330SN/A#pragma GCC system_header
5340SN/A#endif
5350SN/A
5360SN/A#ifdef _LIBCPP_HAS_NO_THREADS
5370SN/A#error <atomic> is not supported on this single threaded system
5380SN/A#else // !_LIBCPP_HAS_NO_THREADS
5390SN/A
5400SN/A_LIBCPP_BEGIN_NAMESPACE_STD
5410SN/A
5420SN/A#if !__has_feature(cxx_atomic) && _GNUC_VER < 407
5430SN/A#error <atomic> is not implemented
5440SN/A#else
5450SN/A
5460SN/Atypedef enum memory_order
5470SN/A{
5480SN/A    memory_order_relaxed, memory_order_consume, memory_order_acquire,
5490SN/A    memory_order_release, memory_order_acq_rel, memory_order_seq_cst
5500SN/A} memory_order;
5510SN/A
5520SN/A#if _GNUC_VER >= 407
5530SN/Anamespace __gcc_atomic {
5540SN/Atemplate <typename _Tp>
5550SN/Astruct __gcc_atomic_t {
5560SN/A  __gcc_atomic_t() _NOEXCEPT {}
5570SN/A  _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT
5580SN/A    : __a_value(value) {}
5590SN/A  _Tp __a_value;
5600SN/A};
5610SN/A#define _Atomic(x) __gcc_atomic::__gcc_atomic_t<x>
5620SN/A
5630SN/Atemplate <typename _Tp> _Tp __create();
5640SN/A
5650SN/Atemplate <typename _Tp, typename _Td>
5660SN/Atypename enable_if<sizeof(_Tp()->__a_value = __create<_Td>()), char>::type
5670SN/A    __test_atomic_assignable(int);
5680SN/Atemplate <typename _Tp, typename _Up>
5690SN/A__two __test_atomic_assignable(...);
5700SN/A
5710SN/Atemplate <typename _Tp, typename _Td>
5720SN/Astruct __can_assign {
5730SN/A  static const bool value =
5740SN/A      sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char);
5750SN/A};
5760SN/A
5770SN/Astatic inline constexpr int __to_gcc_order(memory_order __order) {
5780SN/A  // Avoid switch statement to make this a constexpr.
5790SN/A  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
5800SN/A         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
5810SN/A          (__order == memory_order_release ? __ATOMIC_RELEASE:
5820SN/A           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
5830SN/A            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
5840SN/A              __ATOMIC_CONSUME))));
5850SN/A}
5860SN/A
5870SN/Astatic inline constexpr int __to_gcc_failure_order(memory_order __order) {
5880SN/A  // Avoid switch statement to make this a constexpr.
5890SN/A  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
5900SN/A         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
5910SN/A          (__order == memory_order_release ? __ATOMIC_RELAXED:
5920SN/A           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
5930SN/A            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
5940SN/A              __ATOMIC_CONSUME))));
5950SN/A}
5960SN/A
5970SN/A} // namespace __gcc_atomic
5980SN/A
5990SN/Atemplate <typename _Tp>
6000SN/Astatic inline
6010SN/Atypename enable_if<
6020SN/A    __gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value>::type
6030SN/A__c11_atomic_init(volatile _Atomic(_Tp)* __a,  _Tp __val) {
6040SN/A  __a->__a_value = __val;
6050SN/A}
6060SN/A
6070SN/Atemplate <typename _Tp>
6080SN/Astatic inline
6090SN/Atypename enable_if<
6100SN/A    !__gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value &&
6110SN/A     __gcc_atomic::__can_assign<         _Atomic(_Tp)*, _Tp>::value>::type
6120SN/A__c11_atomic_init(volatile _Atomic(_Tp)* __a,  _Tp __val) {
6130SN/A  // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
6140SN/A  // the default operator= in an object is not volatile, a byte-by-byte copy
6150SN/A  // is required.
6160SN/A  volatile char* to = reinterpret_cast<volatile char*>(&__a->__a_value);
6170SN/A  volatile char* end = to + sizeof(_Tp);
6180SN/A  char* from = reinterpret_cast<char*>(&__val);
6190SN/A  while (to != end) {
6200SN/A    *to++ = *from++;
6210SN/A  }
6220SN/A}
6230SN/A
6240SN/Atemplate <typename _Tp>
6250SN/Astatic inline void __c11_atomic_init(_Atomic(_Tp)* __a,  _Tp __val) {
6260SN/A  __a->__a_value = __val;
6270SN/A}
6280SN/A
6290SN/Astatic inline void __c11_atomic_thread_fence(memory_order __order) {
6300SN/A  __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order));
6310SN/A}
6320SN/A
6330SN/Astatic inline void __c11_atomic_signal_fence(memory_order __order) {
6340SN/A  __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order));
6350SN/A}
6360SN/A
6370SN/Atemplate <typename _Tp>
6380SN/Astatic inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a,  _Tp __val,
6390SN/A                                      memory_order __order) {
6400SN/A  return __atomic_store(&__a->__a_value, &__val,
6410SN/A                        __gcc_atomic::__to_gcc_order(__order));
6420SN/A}
6430SN/A
6440SN/Atemplate <typename _Tp>
6450SN/Astatic inline void __c11_atomic_store(_Atomic(_Tp)* __a,  _Tp __val,
6460SN/A                                      memory_order __order) {
6470SN/A  __atomic_store(&__a->__a_value, &__val,
6480SN/A                 __gcc_atomic::__to_gcc_order(__order));
6490SN/A}
6500SN/A
6510SN/Atemplate <typename _Tp>
6520SN/Astatic inline _Tp __c11_atomic_load(volatile _Atomic(_Tp)* __a,
6530SN/A                                    memory_order __order) {
6540SN/A  _Tp __ret;
6550SN/A  __atomic_load(&__a->__a_value, &__ret,
6560SN/A                __gcc_atomic::__to_gcc_order(__order));
6570SN/A  return __ret;
6580SN/A}
6590SN/A
6600SN/Atemplate <typename _Tp>
6610SN/Astatic inline _Tp __c11_atomic_load(_Atomic(_Tp)* __a, memory_order __order) {
6620SN/A  _Tp __ret;
6630SN/A  __atomic_load(&__a->__a_value, &__ret,
6640SN/A                __gcc_atomic::__to_gcc_order(__order));
6650SN/A  return __ret;
6660SN/A}
6670SN/A
6680SN/Atemplate <typename _Tp>
6690SN/Astatic inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a,
6700SN/A                                        _Tp __value, memory_order __order) {
6710SN/A  _Tp __ret;
6720SN/A  __atomic_exchange(&__a->__a_value, &__value, &__ret,
6730SN/A                    __gcc_atomic::__to_gcc_order(__order));
6740SN/A  return __ret;
6750SN/A}
6760SN/A
6770SN/Atemplate <typename _Tp>
6780SN/Astatic inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value,
6790SN/A                                        memory_order __order) {
6800SN/A  _Tp __ret;
6810SN/A  __atomic_exchange(&__a->__a_value, &__value, &__ret,
6820SN/A                    __gcc_atomic::__to_gcc_order(__order));
6830SN/A  return __ret;
6840SN/A}
6850SN/A
6860SN/Atemplate <typename _Tp>
6870SN/Astatic inline bool __c11_atomic_compare_exchange_strong(
6880SN/A    volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
6890SN/A    memory_order __success, memory_order __failure) {
6900SN/A  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
6910SN/A                                   false,
6920SN/A                                   __gcc_atomic::__to_gcc_order(__success),
6930SN/A                                   __gcc_atomic::__to_gcc_failure_order(__failure));
6940SN/A}
6950SN/A
6960SN/Atemplate <typename _Tp>
6970SN/Astatic inline bool __c11_atomic_compare_exchange_strong(
6980SN/A    _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
6990SN/A    memory_order __failure) {
7000SN/A  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
7010SN/A                                   false,
7020SN/A                                   __gcc_atomic::__to_gcc_order(__success),
7030SN/A                                   __gcc_atomic::__to_gcc_failure_order(__failure));
7040SN/A}
7050SN/A
7060SN/Atemplate <typename _Tp>
7070SN/Astatic inline bool __c11_atomic_compare_exchange_weak(
7080SN/A    volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
7090SN/A    memory_order __success, memory_order __failure) {
7100SN/A  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
7110SN/A                                   true,
7120SN/A                                   __gcc_atomic::__to_gcc_order(__success),
7130SN/A                                   __gcc_atomic::__to_gcc_failure_order(__failure));
7140SN/A}
7150SN/A
7160SN/Atemplate <typename _Tp>
7170SN/Astatic inline bool __c11_atomic_compare_exchange_weak(
7180SN/A    _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
7190SN/A    memory_order __failure) {
7200SN/A  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
7210SN/A                                   true,
722                                   __gcc_atomic::__to_gcc_order(__success),
723                                   __gcc_atomic::__to_gcc_failure_order(__failure));
724}
725
726template <typename _Tp>
727struct __skip_amt { enum {value = 1}; };
728
729template <typename _Tp>
730struct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
731
732// FIXME: Haven't figured out what the spec says about using arrays with
733// atomic_fetch_add. Force a failure rather than creating bad behavior.
734template <typename _Tp>
735struct __skip_amt<_Tp[]> { };
736template <typename _Tp, int n>
737struct __skip_amt<_Tp[n]> { };
738
739template <typename _Tp, typename _Td>
740static inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a,
741                                         _Td __delta, memory_order __order) {
742  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
743                            __gcc_atomic::__to_gcc_order(__order));
744}
745
746template <typename _Tp, typename _Td>
747static inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta,
748                                         memory_order __order) {
749  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
750                            __gcc_atomic::__to_gcc_order(__order));
751}
752
753template <typename _Tp, typename _Td>
754static inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a,
755                                         _Td __delta, memory_order __order) {
756  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
757                            __gcc_atomic::__to_gcc_order(__order));
758}
759
760template <typename _Tp, typename _Td>
761static inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta,
762                                         memory_order __order) {
763  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
764                            __gcc_atomic::__to_gcc_order(__order));
765}
766
767template <typename _Tp>
768static inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a,
769                                         _Tp __pattern, memory_order __order) {
770  return __atomic_fetch_and(&__a->__a_value, __pattern,
771                            __gcc_atomic::__to_gcc_order(__order));
772}
773
774template <typename _Tp>
775static inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a,
776                                         _Tp __pattern, memory_order __order) {
777  return __atomic_fetch_and(&__a->__a_value, __pattern,
778                            __gcc_atomic::__to_gcc_order(__order));
779}
780
781template <typename _Tp>
782static inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a,
783                                        _Tp __pattern, memory_order __order) {
784  return __atomic_fetch_or(&__a->__a_value, __pattern,
785                           __gcc_atomic::__to_gcc_order(__order));
786}
787
788template <typename _Tp>
789static inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern,
790                                        memory_order __order) {
791  return __atomic_fetch_or(&__a->__a_value, __pattern,
792                           __gcc_atomic::__to_gcc_order(__order));
793}
794
795template <typename _Tp>
796static inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a,
797                                         _Tp __pattern, memory_order __order) {
798  return __atomic_fetch_xor(&__a->__a_value, __pattern,
799                            __gcc_atomic::__to_gcc_order(__order));
800}
801
802template <typename _Tp>
803static inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern,
804                                         memory_order __order) {
805  return __atomic_fetch_xor(&__a->__a_value, __pattern,
806                            __gcc_atomic::__to_gcc_order(__order));
807}
808#endif // _GNUC_VER >= 407
809
810template <class _Tp>
811inline _LIBCPP_INLINE_VISIBILITY
812_Tp
813kill_dependency(_Tp __y) _NOEXCEPT
814{
815    return __y;
816}
817
818// general atomic<T>
819
820template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
821struct __atomic_base  // false
822{
823    mutable _Atomic(_Tp) __a_;
824
825    _LIBCPP_INLINE_VISIBILITY
826    bool is_lock_free() const volatile _NOEXCEPT
827    {
828#if __has_feature(cxx_atomic)
829    return __c11_atomic_is_lock_free(sizeof(_Tp));
830#else
831    return __atomic_is_lock_free(sizeof(_Tp), 0);
832#endif
833    }
834    _LIBCPP_INLINE_VISIBILITY
835    bool is_lock_free() const _NOEXCEPT
836        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
837    _LIBCPP_INLINE_VISIBILITY
838    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
839        {__c11_atomic_store(&__a_, __d, __m);}
840    _LIBCPP_INLINE_VISIBILITY
841    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
842        {__c11_atomic_store(&__a_, __d, __m);}
843    _LIBCPP_INLINE_VISIBILITY
844    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
845        {return __c11_atomic_load(&__a_, __m);}
846    _LIBCPP_INLINE_VISIBILITY
847    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
848        {return __c11_atomic_load(&__a_, __m);}
849    _LIBCPP_INLINE_VISIBILITY
850    operator _Tp() const volatile _NOEXCEPT {return load();}
851    _LIBCPP_INLINE_VISIBILITY
852    operator _Tp() const _NOEXCEPT          {return load();}
853    _LIBCPP_INLINE_VISIBILITY
854    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
855        {return __c11_atomic_exchange(&__a_, __d, __m);}
856    _LIBCPP_INLINE_VISIBILITY
857    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
858        {return __c11_atomic_exchange(&__a_, __d, __m);}
859    _LIBCPP_INLINE_VISIBILITY
860    bool compare_exchange_weak(_Tp& __e, _Tp __d,
861                               memory_order __s, memory_order __f) volatile _NOEXCEPT
862        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
863    _LIBCPP_INLINE_VISIBILITY
864    bool compare_exchange_weak(_Tp& __e, _Tp __d,
865                               memory_order __s, memory_order __f) _NOEXCEPT
866        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
867    _LIBCPP_INLINE_VISIBILITY
868    bool compare_exchange_strong(_Tp& __e, _Tp __d,
869                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
870        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
871    _LIBCPP_INLINE_VISIBILITY
872    bool compare_exchange_strong(_Tp& __e, _Tp __d,
873                                 memory_order __s, memory_order __f) _NOEXCEPT
874        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
875    _LIBCPP_INLINE_VISIBILITY
876    bool compare_exchange_weak(_Tp& __e, _Tp __d,
877                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
878        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
879    _LIBCPP_INLINE_VISIBILITY
880    bool compare_exchange_weak(_Tp& __e, _Tp __d,
881                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
882        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
883    _LIBCPP_INLINE_VISIBILITY
884    bool compare_exchange_strong(_Tp& __e, _Tp __d,
885                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
886        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
887    _LIBCPP_INLINE_VISIBILITY
888    bool compare_exchange_strong(_Tp& __e, _Tp __d,
889                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
890        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
891
892    _LIBCPP_INLINE_VISIBILITY
893#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
894    __atomic_base() _NOEXCEPT = default;
895#else
896    __atomic_base() _NOEXCEPT : __a_() {}
897#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
898
899    _LIBCPP_INLINE_VISIBILITY
900    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
901#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
902    __atomic_base(const __atomic_base&) = delete;
903    __atomic_base& operator=(const __atomic_base&) = delete;
904    __atomic_base& operator=(const __atomic_base&) volatile = delete;
905#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
906private:
907    __atomic_base(const __atomic_base&);
908    __atomic_base& operator=(const __atomic_base&);
909    __atomic_base& operator=(const __atomic_base&) volatile;
910#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
911};
912
913// atomic<Integral>
914
915template <class _Tp>
916struct __atomic_base<_Tp, true>
917    : public __atomic_base<_Tp, false>
918{
919    typedef __atomic_base<_Tp, false> __base;
920    _LIBCPP_INLINE_VISIBILITY
921    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
922    _LIBCPP_INLINE_VISIBILITY
923    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
924
925    _LIBCPP_INLINE_VISIBILITY
926    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
927        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
928    _LIBCPP_INLINE_VISIBILITY
929    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
930        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
931    _LIBCPP_INLINE_VISIBILITY
932    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
933        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
934    _LIBCPP_INLINE_VISIBILITY
935    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
936        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
937    _LIBCPP_INLINE_VISIBILITY
938    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
939        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
940    _LIBCPP_INLINE_VISIBILITY
941    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
942        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
943    _LIBCPP_INLINE_VISIBILITY
944    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
945        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
946    _LIBCPP_INLINE_VISIBILITY
947    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
948        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
949    _LIBCPP_INLINE_VISIBILITY
950    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
951        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
952    _LIBCPP_INLINE_VISIBILITY
953    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
954        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
955
956    _LIBCPP_INLINE_VISIBILITY
957    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
958    _LIBCPP_INLINE_VISIBILITY
959    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
960    _LIBCPP_INLINE_VISIBILITY
961    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
962    _LIBCPP_INLINE_VISIBILITY
963    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
964    _LIBCPP_INLINE_VISIBILITY
965    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
966    _LIBCPP_INLINE_VISIBILITY
967    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
968    _LIBCPP_INLINE_VISIBILITY
969    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
970    _LIBCPP_INLINE_VISIBILITY
971    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
972    _LIBCPP_INLINE_VISIBILITY
973    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
974    _LIBCPP_INLINE_VISIBILITY
975    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
976    _LIBCPP_INLINE_VISIBILITY
977    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
978    _LIBCPP_INLINE_VISIBILITY
979    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
980    _LIBCPP_INLINE_VISIBILITY
981    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
982    _LIBCPP_INLINE_VISIBILITY
983    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
984    _LIBCPP_INLINE_VISIBILITY
985    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
986    _LIBCPP_INLINE_VISIBILITY
987    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
988    _LIBCPP_INLINE_VISIBILITY
989    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
990    _LIBCPP_INLINE_VISIBILITY
991    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
992};
993
994// atomic<T>
995
996template <class _Tp>
997struct atomic
998    : public __atomic_base<_Tp>
999{
1000    typedef __atomic_base<_Tp> __base;
1001    _LIBCPP_INLINE_VISIBILITY
1002    atomic() _NOEXCEPT _LIBCPP_DEFAULT
1003    _LIBCPP_INLINE_VISIBILITY
1004    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
1005
1006    _LIBCPP_INLINE_VISIBILITY
1007    _Tp operator=(_Tp __d) volatile _NOEXCEPT
1008        {__base::store(__d); return __d;}
1009    _LIBCPP_INLINE_VISIBILITY
1010    _Tp operator=(_Tp __d) _NOEXCEPT
1011        {__base::store(__d); return __d;}
1012};
1013
1014// atomic<T*>
1015
1016template <class _Tp>
1017struct atomic<_Tp*>
1018    : public __atomic_base<_Tp*>
1019{
1020    typedef __atomic_base<_Tp*> __base;
1021    _LIBCPP_INLINE_VISIBILITY
1022    atomic() _NOEXCEPT _LIBCPP_DEFAULT
1023    _LIBCPP_INLINE_VISIBILITY
1024    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
1025
1026    _LIBCPP_INLINE_VISIBILITY
1027    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
1028        {__base::store(__d); return __d;}
1029    _LIBCPP_INLINE_VISIBILITY
1030    _Tp* operator=(_Tp* __d) _NOEXCEPT
1031        {__base::store(__d); return __d;}
1032
1033    _LIBCPP_INLINE_VISIBILITY
1034    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
1035                                                                        volatile _NOEXCEPT
1036        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
1037    _LIBCPP_INLINE_VISIBILITY
1038    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1039        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
1040    _LIBCPP_INLINE_VISIBILITY
1041    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
1042                                                                        volatile _NOEXCEPT
1043        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
1044    _LIBCPP_INLINE_VISIBILITY
1045    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1046        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
1047
1048    _LIBCPP_INLINE_VISIBILITY
1049    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
1050    _LIBCPP_INLINE_VISIBILITY
1051    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
1052    _LIBCPP_INLINE_VISIBILITY
1053    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
1054    _LIBCPP_INLINE_VISIBILITY
1055    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
1056    _LIBCPP_INLINE_VISIBILITY
1057    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
1058    _LIBCPP_INLINE_VISIBILITY
1059    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
1060    _LIBCPP_INLINE_VISIBILITY
1061    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
1062    _LIBCPP_INLINE_VISIBILITY
1063    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
1064    _LIBCPP_INLINE_VISIBILITY
1065    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1066    _LIBCPP_INLINE_VISIBILITY
1067    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
1068    _LIBCPP_INLINE_VISIBILITY
1069    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1070    _LIBCPP_INLINE_VISIBILITY
1071    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1072};
1073
1074// atomic_is_lock_free
1075
1076template <class _Tp>
1077inline _LIBCPP_INLINE_VISIBILITY
1078bool
1079atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
1080{
1081    return __o->is_lock_free();
1082}
1083
1084template <class _Tp>
1085inline _LIBCPP_INLINE_VISIBILITY
1086bool
1087atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
1088{
1089    return __o->is_lock_free();
1090}
1091
1092// atomic_init
1093
1094template <class _Tp>
1095inline _LIBCPP_INLINE_VISIBILITY
1096void
1097atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1098{
1099    __c11_atomic_init(&__o->__a_, __d);
1100}
1101
1102template <class _Tp>
1103inline _LIBCPP_INLINE_VISIBILITY
1104void
1105atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1106{
1107    __c11_atomic_init(&__o->__a_, __d);
1108}
1109
1110// atomic_store
1111
1112template <class _Tp>
1113inline _LIBCPP_INLINE_VISIBILITY
1114void
1115atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1116{
1117    __o->store(__d);
1118}
1119
1120template <class _Tp>
1121inline _LIBCPP_INLINE_VISIBILITY
1122void
1123atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1124{
1125    __o->store(__d);
1126}
1127
1128// atomic_store_explicit
1129
1130template <class _Tp>
1131inline _LIBCPP_INLINE_VISIBILITY
1132void
1133atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1134{
1135    __o->store(__d, __m);
1136}
1137
1138template <class _Tp>
1139inline _LIBCPP_INLINE_VISIBILITY
1140void
1141atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1142{
1143    __o->store(__d, __m);
1144}
1145
1146// atomic_load
1147
1148template <class _Tp>
1149inline _LIBCPP_INLINE_VISIBILITY
1150_Tp
1151atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
1152{
1153    return __o->load();
1154}
1155
1156template <class _Tp>
1157inline _LIBCPP_INLINE_VISIBILITY
1158_Tp
1159atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
1160{
1161    return __o->load();
1162}
1163
1164// atomic_load_explicit
1165
1166template <class _Tp>
1167inline _LIBCPP_INLINE_VISIBILITY
1168_Tp
1169atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1170{
1171    return __o->load(__m);
1172}
1173
1174template <class _Tp>
1175inline _LIBCPP_INLINE_VISIBILITY
1176_Tp
1177atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1178{
1179    return __o->load(__m);
1180}
1181
1182// atomic_exchange
1183
1184template <class _Tp>
1185inline _LIBCPP_INLINE_VISIBILITY
1186_Tp
1187atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1188{
1189    return __o->exchange(__d);
1190}
1191
1192template <class _Tp>
1193inline _LIBCPP_INLINE_VISIBILITY
1194_Tp
1195atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1196{
1197    return __o->exchange(__d);
1198}
1199
1200// atomic_exchange_explicit
1201
1202template <class _Tp>
1203inline _LIBCPP_INLINE_VISIBILITY
1204_Tp
1205atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1206{
1207    return __o->exchange(__d, __m);
1208}
1209
1210template <class _Tp>
1211inline _LIBCPP_INLINE_VISIBILITY
1212_Tp
1213atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1214{
1215    return __o->exchange(__d, __m);
1216}
1217
1218// atomic_compare_exchange_weak
1219
1220template <class _Tp>
1221inline _LIBCPP_INLINE_VISIBILITY
1222bool
1223atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1224{
1225    return __o->compare_exchange_weak(*__e, __d);
1226}
1227
1228template <class _Tp>
1229inline _LIBCPP_INLINE_VISIBILITY
1230bool
1231atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1232{
1233    return __o->compare_exchange_weak(*__e, __d);
1234}
1235
1236// atomic_compare_exchange_strong
1237
1238template <class _Tp>
1239inline _LIBCPP_INLINE_VISIBILITY
1240bool
1241atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1242{
1243    return __o->compare_exchange_strong(*__e, __d);
1244}
1245
1246template <class _Tp>
1247inline _LIBCPP_INLINE_VISIBILITY
1248bool
1249atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1250{
1251    return __o->compare_exchange_strong(*__e, __d);
1252}
1253
1254// atomic_compare_exchange_weak_explicit
1255
1256template <class _Tp>
1257inline _LIBCPP_INLINE_VISIBILITY
1258bool
1259atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
1260                                      _Tp __d,
1261                                      memory_order __s, memory_order __f) _NOEXCEPT
1262{
1263    return __o->compare_exchange_weak(*__e, __d, __s, __f);
1264}
1265
1266template <class _Tp>
1267inline _LIBCPP_INLINE_VISIBILITY
1268bool
1269atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
1270                                      memory_order __s, memory_order __f) _NOEXCEPT
1271{
1272    return __o->compare_exchange_weak(*__e, __d, __s, __f);
1273}
1274
1275// atomic_compare_exchange_strong_explicit
1276
1277template <class _Tp>
1278inline _LIBCPP_INLINE_VISIBILITY
1279bool
1280atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1281                                        _Tp* __e, _Tp __d,
1282                                        memory_order __s, memory_order __f) _NOEXCEPT
1283{
1284    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1285}
1286
1287template <class _Tp>
1288inline _LIBCPP_INLINE_VISIBILITY
1289bool
1290atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1291                                        _Tp __d,
1292                                        memory_order __s, memory_order __f) _NOEXCEPT
1293{
1294    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1295}
1296
1297// atomic_fetch_add
1298
1299template <class _Tp>
1300inline _LIBCPP_INLINE_VISIBILITY
1301typename enable_if
1302<
1303    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1304    _Tp
1305>::type
1306atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1307{
1308    return __o->fetch_add(__op);
1309}
1310
1311template <class _Tp>
1312inline _LIBCPP_INLINE_VISIBILITY
1313typename enable_if
1314<
1315    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1316    _Tp
1317>::type
1318atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1319{
1320    return __o->fetch_add(__op);
1321}
1322
1323template <class _Tp>
1324inline _LIBCPP_INLINE_VISIBILITY
1325_Tp*
1326atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1327{
1328    return __o->fetch_add(__op);
1329}
1330
1331template <class _Tp>
1332inline _LIBCPP_INLINE_VISIBILITY
1333_Tp*
1334atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1335{
1336    return __o->fetch_add(__op);
1337}
1338
1339// atomic_fetch_add_explicit
1340
1341template <class _Tp>
1342inline _LIBCPP_INLINE_VISIBILITY
1343typename enable_if
1344<
1345    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1346    _Tp
1347>::type
1348atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1349{
1350    return __o->fetch_add(__op, __m);
1351}
1352
1353template <class _Tp>
1354inline _LIBCPP_INLINE_VISIBILITY
1355typename enable_if
1356<
1357    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1358    _Tp
1359>::type
1360atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1361{
1362    return __o->fetch_add(__op, __m);
1363}
1364
1365template <class _Tp>
1366inline _LIBCPP_INLINE_VISIBILITY
1367_Tp*
1368atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1369                          memory_order __m) _NOEXCEPT
1370{
1371    return __o->fetch_add(__op, __m);
1372}
1373
1374template <class _Tp>
1375inline _LIBCPP_INLINE_VISIBILITY
1376_Tp*
1377atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
1378{
1379    return __o->fetch_add(__op, __m);
1380}
1381
1382// atomic_fetch_sub
1383
1384template <class _Tp>
1385inline _LIBCPP_INLINE_VISIBILITY
1386typename enable_if
1387<
1388    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1389    _Tp
1390>::type
1391atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1392{
1393    return __o->fetch_sub(__op);
1394}
1395
1396template <class _Tp>
1397inline _LIBCPP_INLINE_VISIBILITY
1398typename enable_if
1399<
1400    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1401    _Tp
1402>::type
1403atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1404{
1405    return __o->fetch_sub(__op);
1406}
1407
1408template <class _Tp>
1409inline _LIBCPP_INLINE_VISIBILITY
1410_Tp*
1411atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1412{
1413    return __o->fetch_sub(__op);
1414}
1415
1416template <class _Tp>
1417inline _LIBCPP_INLINE_VISIBILITY
1418_Tp*
1419atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1420{
1421    return __o->fetch_sub(__op);
1422}
1423
1424// atomic_fetch_sub_explicit
1425
1426template <class _Tp>
1427inline _LIBCPP_INLINE_VISIBILITY
1428typename enable_if
1429<
1430    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1431    _Tp
1432>::type
1433atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1434{
1435    return __o->fetch_sub(__op, __m);
1436}
1437
1438template <class _Tp>
1439inline _LIBCPP_INLINE_VISIBILITY
1440typename enable_if
1441<
1442    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1443    _Tp
1444>::type
1445atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1446{
1447    return __o->fetch_sub(__op, __m);
1448}
1449
1450template <class _Tp>
1451inline _LIBCPP_INLINE_VISIBILITY
1452_Tp*
1453atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1454                          memory_order __m) _NOEXCEPT
1455{
1456    return __o->fetch_sub(__op, __m);
1457}
1458
1459template <class _Tp>
1460inline _LIBCPP_INLINE_VISIBILITY
1461_Tp*
1462atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
1463{
1464    return __o->fetch_sub(__op, __m);
1465}
1466
1467// atomic_fetch_and
1468
1469template <class _Tp>
1470inline _LIBCPP_INLINE_VISIBILITY
1471typename enable_if
1472<
1473    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1474    _Tp
1475>::type
1476atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1477{
1478    return __o->fetch_and(__op);
1479}
1480
1481template <class _Tp>
1482inline _LIBCPP_INLINE_VISIBILITY
1483typename enable_if
1484<
1485    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1486    _Tp
1487>::type
1488atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1489{
1490    return __o->fetch_and(__op);
1491}
1492
1493// atomic_fetch_and_explicit
1494
1495template <class _Tp>
1496inline _LIBCPP_INLINE_VISIBILITY
1497typename enable_if
1498<
1499    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1500    _Tp
1501>::type
1502atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1503{
1504    return __o->fetch_and(__op, __m);
1505}
1506
1507template <class _Tp>
1508inline _LIBCPP_INLINE_VISIBILITY
1509typename enable_if
1510<
1511    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1512    _Tp
1513>::type
1514atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1515{
1516    return __o->fetch_and(__op, __m);
1517}
1518
1519// atomic_fetch_or
1520
1521template <class _Tp>
1522inline _LIBCPP_INLINE_VISIBILITY
1523typename enable_if
1524<
1525    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1526    _Tp
1527>::type
1528atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1529{
1530    return __o->fetch_or(__op);
1531}
1532
1533template <class _Tp>
1534inline _LIBCPP_INLINE_VISIBILITY
1535typename enable_if
1536<
1537    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1538    _Tp
1539>::type
1540atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1541{
1542    return __o->fetch_or(__op);
1543}
1544
1545// atomic_fetch_or_explicit
1546
1547template <class _Tp>
1548inline _LIBCPP_INLINE_VISIBILITY
1549typename enable_if
1550<
1551    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1552    _Tp
1553>::type
1554atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1555{
1556    return __o->fetch_or(__op, __m);
1557}
1558
1559template <class _Tp>
1560inline _LIBCPP_INLINE_VISIBILITY
1561typename enable_if
1562<
1563    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1564    _Tp
1565>::type
1566atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1567{
1568    return __o->fetch_or(__op, __m);
1569}
1570
1571// atomic_fetch_xor
1572
1573template <class _Tp>
1574inline _LIBCPP_INLINE_VISIBILITY
1575typename enable_if
1576<
1577    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1578    _Tp
1579>::type
1580atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1581{
1582    return __o->fetch_xor(__op);
1583}
1584
1585template <class _Tp>
1586inline _LIBCPP_INLINE_VISIBILITY
1587typename enable_if
1588<
1589    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1590    _Tp
1591>::type
1592atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1593{
1594    return __o->fetch_xor(__op);
1595}
1596
1597// atomic_fetch_xor_explicit
1598
1599template <class _Tp>
1600inline _LIBCPP_INLINE_VISIBILITY
1601typename enable_if
1602<
1603    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1604    _Tp
1605>::type
1606atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1607{
1608    return __o->fetch_xor(__op, __m);
1609}
1610
1611template <class _Tp>
1612inline _LIBCPP_INLINE_VISIBILITY
1613typename enable_if
1614<
1615    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1616    _Tp
1617>::type
1618atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1619{
1620    return __o->fetch_xor(__op, __m);
1621}
1622
1623// flag type and operations
1624
1625typedef struct atomic_flag
1626{
1627    _Atomic(bool) __a_;
1628
1629    _LIBCPP_INLINE_VISIBILITY
1630    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1631        {return __c11_atomic_exchange(&__a_, true, __m);}
1632    _LIBCPP_INLINE_VISIBILITY
1633    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1634        {return __c11_atomic_exchange(&__a_, true, __m);}
1635    _LIBCPP_INLINE_VISIBILITY
1636    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1637        {__c11_atomic_store(&__a_, false, __m);}
1638    _LIBCPP_INLINE_VISIBILITY
1639    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1640        {__c11_atomic_store(&__a_, false, __m);}
1641
1642    _LIBCPP_INLINE_VISIBILITY
1643#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
1644    atomic_flag() _NOEXCEPT = default;
1645#else
1646    atomic_flag() _NOEXCEPT : __a_() {}
1647#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
1648
1649    _LIBCPP_INLINE_VISIBILITY
1650    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {}
1651
1652#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1653    atomic_flag(const atomic_flag&) = delete;
1654    atomic_flag& operator=(const atomic_flag&) = delete;
1655    atomic_flag& operator=(const atomic_flag&) volatile = delete;
1656#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1657private:
1658    atomic_flag(const atomic_flag&);
1659    atomic_flag& operator=(const atomic_flag&);
1660    atomic_flag& operator=(const atomic_flag&) volatile;
1661#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1662} atomic_flag;
1663
1664inline _LIBCPP_INLINE_VISIBILITY
1665bool
1666atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
1667{
1668    return __o->test_and_set();
1669}
1670
1671inline _LIBCPP_INLINE_VISIBILITY
1672bool
1673atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
1674{
1675    return __o->test_and_set();
1676}
1677
1678inline _LIBCPP_INLINE_VISIBILITY
1679bool
1680atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
1681{
1682    return __o->test_and_set(__m);
1683}
1684
1685inline _LIBCPP_INLINE_VISIBILITY
1686bool
1687atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
1688{
1689    return __o->test_and_set(__m);
1690}
1691
1692inline _LIBCPP_INLINE_VISIBILITY
1693void
1694atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
1695{
1696    __o->clear();
1697}
1698
1699inline _LIBCPP_INLINE_VISIBILITY
1700void
1701atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
1702{
1703    __o->clear();
1704}
1705
1706inline _LIBCPP_INLINE_VISIBILITY
1707void
1708atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
1709{
1710    __o->clear(__m);
1711}
1712
1713inline _LIBCPP_INLINE_VISIBILITY
1714void
1715atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
1716{
1717    __o->clear(__m);
1718}
1719
1720// fences
1721
1722inline _LIBCPP_INLINE_VISIBILITY
1723void
1724atomic_thread_fence(memory_order __m) _NOEXCEPT
1725{
1726    __c11_atomic_thread_fence(__m);
1727}
1728
1729inline _LIBCPP_INLINE_VISIBILITY
1730void
1731atomic_signal_fence(memory_order __m) _NOEXCEPT
1732{
1733    __c11_atomic_signal_fence(__m);
1734}
1735
1736// Atomics for standard typedef types
1737
1738typedef atomic<bool>               atomic_bool;
1739typedef atomic<char>               atomic_char;
1740typedef atomic<signed char>        atomic_schar;
1741typedef atomic<unsigned char>      atomic_uchar;
1742typedef atomic<short>              atomic_short;
1743typedef atomic<unsigned short>     atomic_ushort;
1744typedef atomic<int>                atomic_int;
1745typedef atomic<unsigned int>       atomic_uint;
1746typedef atomic<long>               atomic_long;
1747typedef atomic<unsigned long>      atomic_ulong;
1748typedef atomic<long long>          atomic_llong;
1749typedef atomic<unsigned long long> atomic_ullong;
1750typedef atomic<char16_t>           atomic_char16_t;
1751typedef atomic<char32_t>           atomic_char32_t;
1752typedef atomic<wchar_t>            atomic_wchar_t;
1753
1754typedef atomic<int_least8_t>   atomic_int_least8_t;
1755typedef atomic<uint_least8_t>  atomic_uint_least8_t;
1756typedef atomic<int_least16_t>  atomic_int_least16_t;
1757typedef atomic<uint_least16_t> atomic_uint_least16_t;
1758typedef atomic<int_least32_t>  atomic_int_least32_t;
1759typedef atomic<uint_least32_t> atomic_uint_least32_t;
1760typedef atomic<int_least64_t>  atomic_int_least64_t;
1761typedef atomic<uint_least64_t> atomic_uint_least64_t;
1762
1763typedef atomic<int_fast8_t>   atomic_int_fast8_t;
1764typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
1765typedef atomic<int_fast16_t>  atomic_int_fast16_t;
1766typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1767typedef atomic<int_fast32_t>  atomic_int_fast32_t;
1768typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1769typedef atomic<int_fast64_t>  atomic_int_fast64_t;
1770typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1771
1772typedef atomic<intptr_t>  atomic_intptr_t;
1773typedef atomic<uintptr_t> atomic_uintptr_t;
1774typedef atomic<size_t>    atomic_size_t;
1775typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1776typedef atomic<intmax_t>  atomic_intmax_t;
1777typedef atomic<uintmax_t> atomic_uintmax_t;
1778
1779#define ATOMIC_FLAG_INIT {false}
1780#define ATOMIC_VAR_INIT(__v) {__v}
1781
1782// lock-free property
1783
1784#define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
1785#define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
1786#define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1787#define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1788#define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1789#define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
1790#define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
1791#define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
1792#define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
1793#define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
1794
1795#endif  //  !__has_feature(cxx_atomic)
1796
1797_LIBCPP_END_NAMESPACE_STD
1798
1799#endif  // !_LIBCPP_HAS_NO_THREADS
1800
1801#endif  // _LIBCPP_ATOMIC
1802