xref: /freebsd/contrib/llvm-project/libcxx/include/atomic (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric// -*- C++ -*-
2*0b57cec5SDimitry Andric//===--------------------------- atomic -----------------------------------===//
3*0b57cec5SDimitry Andric//
4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*0b57cec5SDimitry Andric//
8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9*0b57cec5SDimitry Andric
10*0b57cec5SDimitry Andric#ifndef _LIBCPP_ATOMIC
11*0b57cec5SDimitry Andric#define _LIBCPP_ATOMIC
12*0b57cec5SDimitry Andric
13*0b57cec5SDimitry Andric/*
14*0b57cec5SDimitry Andric    atomic synopsis
15*0b57cec5SDimitry Andric
16*0b57cec5SDimitry Andricnamespace std
17*0b57cec5SDimitry Andric{
18*0b57cec5SDimitry Andric
19*0b57cec5SDimitry Andric// feature test macro
20*0b57cec5SDimitry Andric
21*0b57cec5SDimitry Andric#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10
22*0b57cec5SDimitry Andric
23*0b57cec5SDimitry Andric // order and consistency
24*0b57cec5SDimitry Andric
25*0b57cec5SDimitry Andric enum memory_order: unspecified // enum class in C++20
26*0b57cec5SDimitry Andric {
27*0b57cec5SDimitry Andric    relaxed,
28*0b57cec5SDimitry Andric    consume, // load-consume
29*0b57cec5SDimitry Andric    acquire, // load-acquire
30*0b57cec5SDimitry Andric    release, // store-release
31*0b57cec5SDimitry Andric    acq_rel, // store-release load-acquire
32*0b57cec5SDimitry Andric    seq_cst // store-release load-acquire
33*0b57cec5SDimitry Andric };
34*0b57cec5SDimitry Andric
35*0b57cec5SDimitry Andric inline constexpr auto memory_order_relaxed = memory_order::relaxed;
36*0b57cec5SDimitry Andric inline constexpr auto memory_order_consume = memory_order::consume;
37*0b57cec5SDimitry Andric inline constexpr auto memory_order_acquire = memory_order::acquire;
38*0b57cec5SDimitry Andric inline constexpr auto memory_order_release = memory_order::release;
39*0b57cec5SDimitry Andric inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
40*0b57cec5SDimitry Andric inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
41*0b57cec5SDimitry Andric
42*0b57cec5SDimitry Andrictemplate <class T> T kill_dependency(T y) noexcept;
43*0b57cec5SDimitry Andric
44*0b57cec5SDimitry Andric// lock-free property
45*0b57cec5SDimitry Andric
46*0b57cec5SDimitry Andric#define ATOMIC_BOOL_LOCK_FREE unspecified
47*0b57cec5SDimitry Andric#define ATOMIC_CHAR_LOCK_FREE unspecified
48*0b57cec5SDimitry Andric#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
49*0b57cec5SDimitry Andric#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
50*0b57cec5SDimitry Andric#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
51*0b57cec5SDimitry Andric#define ATOMIC_SHORT_LOCK_FREE unspecified
52*0b57cec5SDimitry Andric#define ATOMIC_INT_LOCK_FREE unspecified
53*0b57cec5SDimitry Andric#define ATOMIC_LONG_LOCK_FREE unspecified
54*0b57cec5SDimitry Andric#define ATOMIC_LLONG_LOCK_FREE unspecified
55*0b57cec5SDimitry Andric#define ATOMIC_POINTER_LOCK_FREE unspecified
56*0b57cec5SDimitry Andric
57*0b57cec5SDimitry Andric// flag type and operations
58*0b57cec5SDimitry Andric
59*0b57cec5SDimitry Andrictypedef struct atomic_flag
60*0b57cec5SDimitry Andric{
61*0b57cec5SDimitry Andric    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
62*0b57cec5SDimitry Andric    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
63*0b57cec5SDimitry Andric    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
64*0b57cec5SDimitry Andric    void clear(memory_order m = memory_order_seq_cst) noexcept;
65*0b57cec5SDimitry Andric    atomic_flag()  noexcept = default;
66*0b57cec5SDimitry Andric    atomic_flag(const atomic_flag&) = delete;
67*0b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) = delete;
68*0b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile = delete;
69*0b57cec5SDimitry Andric} atomic_flag;
70*0b57cec5SDimitry Andric
71*0b57cec5SDimitry Andricbool
72*0b57cec5SDimitry Andric    atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
73*0b57cec5SDimitry Andric
74*0b57cec5SDimitry Andricbool
75*0b57cec5SDimitry Andric    atomic_flag_test_and_set(atomic_flag* obj) noexcept;
76*0b57cec5SDimitry Andric
77*0b57cec5SDimitry Andricbool
78*0b57cec5SDimitry Andric    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
79*0b57cec5SDimitry Andric                                      memory_order m) noexcept;
80*0b57cec5SDimitry Andric
81*0b57cec5SDimitry Andricbool
82*0b57cec5SDimitry Andric    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
83*0b57cec5SDimitry Andric
84*0b57cec5SDimitry Andricvoid
85*0b57cec5SDimitry Andric    atomic_flag_clear(volatile atomic_flag* obj) noexcept;
86*0b57cec5SDimitry Andric
87*0b57cec5SDimitry Andricvoid
88*0b57cec5SDimitry Andric    atomic_flag_clear(atomic_flag* obj) noexcept;
89*0b57cec5SDimitry Andric
90*0b57cec5SDimitry Andricvoid
91*0b57cec5SDimitry Andric    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
92*0b57cec5SDimitry Andric
93*0b57cec5SDimitry Andricvoid
94*0b57cec5SDimitry Andric    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
95*0b57cec5SDimitry Andric
96*0b57cec5SDimitry Andric#define ATOMIC_FLAG_INIT see below
97*0b57cec5SDimitry Andric#define ATOMIC_VAR_INIT(value) see below
98*0b57cec5SDimitry Andric
99*0b57cec5SDimitry Andrictemplate <class T>
100*0b57cec5SDimitry Andricstruct atomic
101*0b57cec5SDimitry Andric{
102*0b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
103*0b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
104*0b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
105*0b57cec5SDimitry Andric    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
106*0b57cec5SDimitry Andric    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
107*0b57cec5SDimitry Andric    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
108*0b57cec5SDimitry Andric    T load(memory_order m = memory_order_seq_cst) const noexcept;
109*0b57cec5SDimitry Andric    operator T() const volatile noexcept;
110*0b57cec5SDimitry Andric    operator T() const noexcept;
111*0b57cec5SDimitry Andric    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
112*0b57cec5SDimitry Andric    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
113*0b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
114*0b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
115*0b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
116*0b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
117*0b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
118*0b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
119*0b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
120*0b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
121*0b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
122*0b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
123*0b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
124*0b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
125*0b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
126*0b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
127*0b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
128*0b57cec5SDimitry Andric
129*0b57cec5SDimitry Andric    atomic() noexcept = default;
130*0b57cec5SDimitry Andric    constexpr atomic(T desr) noexcept;
131*0b57cec5SDimitry Andric    atomic(const atomic&) = delete;
132*0b57cec5SDimitry Andric    atomic& operator=(const atomic&) = delete;
133*0b57cec5SDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
134*0b57cec5SDimitry Andric    T operator=(T) volatile noexcept;
135*0b57cec5SDimitry Andric    T operator=(T) noexcept;
136*0b57cec5SDimitry Andric};
137*0b57cec5SDimitry Andric
138*0b57cec5SDimitry Andrictemplate <>
139*0b57cec5SDimitry Andricstruct atomic<integral>
140*0b57cec5SDimitry Andric{
141*0b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
142*0b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
143*0b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
144*0b57cec5SDimitry Andric    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
145*0b57cec5SDimitry Andric    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
146*0b57cec5SDimitry Andric    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
147*0b57cec5SDimitry Andric    integral load(memory_order m = memory_order_seq_cst) const noexcept;
148*0b57cec5SDimitry Andric    operator integral() const volatile noexcept;
149*0b57cec5SDimitry Andric    operator integral() const noexcept;
150*0b57cec5SDimitry Andric    integral exchange(integral desr,
151*0b57cec5SDimitry Andric                      memory_order m = memory_order_seq_cst) volatile noexcept;
152*0b57cec5SDimitry Andric    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
153*0b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
154*0b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
155*0b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
156*0b57cec5SDimitry Andric                               memory_order s, memory_order f) noexcept;
157*0b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
158*0b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
159*0b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
160*0b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
161*0b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
162*0b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
163*0b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
164*0b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
165*0b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
166*0b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
167*0b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
168*0b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
169*0b57cec5SDimitry Andric
170*0b57cec5SDimitry Andric    integral
171*0b57cec5SDimitry Andric        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
172*0b57cec5SDimitry Andric    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
173*0b57cec5SDimitry Andric    integral
174*0b57cec5SDimitry Andric        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
175*0b57cec5SDimitry Andric    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
176*0b57cec5SDimitry Andric    integral
177*0b57cec5SDimitry Andric        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
178*0b57cec5SDimitry Andric    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
179*0b57cec5SDimitry Andric    integral
180*0b57cec5SDimitry Andric        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
181*0b57cec5SDimitry Andric    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
182*0b57cec5SDimitry Andric    integral
183*0b57cec5SDimitry Andric        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
184*0b57cec5SDimitry Andric    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
185*0b57cec5SDimitry Andric
186*0b57cec5SDimitry Andric    atomic() noexcept = default;
187*0b57cec5SDimitry Andric    constexpr atomic(integral desr) noexcept;
188*0b57cec5SDimitry Andric    atomic(const atomic&) = delete;
189*0b57cec5SDimitry Andric    atomic& operator=(const atomic&) = delete;
190*0b57cec5SDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
191*0b57cec5SDimitry Andric    integral operator=(integral desr) volatile noexcept;
192*0b57cec5SDimitry Andric    integral operator=(integral desr) noexcept;
193*0b57cec5SDimitry Andric
194*0b57cec5SDimitry Andric    integral operator++(int) volatile noexcept;
195*0b57cec5SDimitry Andric    integral operator++(int) noexcept;
196*0b57cec5SDimitry Andric    integral operator--(int) volatile noexcept;
197*0b57cec5SDimitry Andric    integral operator--(int) noexcept;
198*0b57cec5SDimitry Andric    integral operator++() volatile noexcept;
199*0b57cec5SDimitry Andric    integral operator++() noexcept;
200*0b57cec5SDimitry Andric    integral operator--() volatile noexcept;
201*0b57cec5SDimitry Andric    integral operator--() noexcept;
202*0b57cec5SDimitry Andric    integral operator+=(integral op) volatile noexcept;
203*0b57cec5SDimitry Andric    integral operator+=(integral op) noexcept;
204*0b57cec5SDimitry Andric    integral operator-=(integral op) volatile noexcept;
205*0b57cec5SDimitry Andric    integral operator-=(integral op) noexcept;
206*0b57cec5SDimitry Andric    integral operator&=(integral op) volatile noexcept;
207*0b57cec5SDimitry Andric    integral operator&=(integral op) noexcept;
208*0b57cec5SDimitry Andric    integral operator|=(integral op) volatile noexcept;
209*0b57cec5SDimitry Andric    integral operator|=(integral op) noexcept;
210*0b57cec5SDimitry Andric    integral operator^=(integral op) volatile noexcept;
211*0b57cec5SDimitry Andric    integral operator^=(integral op) noexcept;
212*0b57cec5SDimitry Andric};
213*0b57cec5SDimitry Andric
214*0b57cec5SDimitry Andrictemplate <class T>
215*0b57cec5SDimitry Andricstruct atomic<T*>
216*0b57cec5SDimitry Andric{
217*0b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
218*0b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
219*0b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
220*0b57cec5SDimitry Andric    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
221*0b57cec5SDimitry Andric    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
222*0b57cec5SDimitry Andric    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
223*0b57cec5SDimitry Andric    T* load(memory_order m = memory_order_seq_cst) const noexcept;
224*0b57cec5SDimitry Andric    operator T*() const volatile noexcept;
225*0b57cec5SDimitry Andric    operator T*() const noexcept;
226*0b57cec5SDimitry Andric    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
227*0b57cec5SDimitry Andric    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
228*0b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
229*0b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
230*0b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
231*0b57cec5SDimitry Andric                               memory_order s, memory_order f) noexcept;
232*0b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
233*0b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
234*0b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
235*0b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
236*0b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
237*0b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
238*0b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
239*0b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
240*0b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
241*0b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
242*0b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
243*0b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
244*0b57cec5SDimitry Andric    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
245*0b57cec5SDimitry Andric    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
246*0b57cec5SDimitry Andric    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
247*0b57cec5SDimitry Andric    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
248*0b57cec5SDimitry Andric
249*0b57cec5SDimitry Andric    atomic() noexcept = default;
250*0b57cec5SDimitry Andric    constexpr atomic(T* desr) noexcept;
251*0b57cec5SDimitry Andric    atomic(const atomic&) = delete;
252*0b57cec5SDimitry Andric    atomic& operator=(const atomic&) = delete;
253*0b57cec5SDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
254*0b57cec5SDimitry Andric
255*0b57cec5SDimitry Andric    T* operator=(T*) volatile noexcept;
256*0b57cec5SDimitry Andric    T* operator=(T*) noexcept;
257*0b57cec5SDimitry Andric    T* operator++(int) volatile noexcept;
258*0b57cec5SDimitry Andric    T* operator++(int) noexcept;
259*0b57cec5SDimitry Andric    T* operator--(int) volatile noexcept;
260*0b57cec5SDimitry Andric    T* operator--(int) noexcept;
261*0b57cec5SDimitry Andric    T* operator++() volatile noexcept;
262*0b57cec5SDimitry Andric    T* operator++() noexcept;
263*0b57cec5SDimitry Andric    T* operator--() volatile noexcept;
264*0b57cec5SDimitry Andric    T* operator--() noexcept;
265*0b57cec5SDimitry Andric    T* operator+=(ptrdiff_t op) volatile noexcept;
266*0b57cec5SDimitry Andric    T* operator+=(ptrdiff_t op) noexcept;
267*0b57cec5SDimitry Andric    T* operator-=(ptrdiff_t op) volatile noexcept;
268*0b57cec5SDimitry Andric    T* operator-=(ptrdiff_t op) noexcept;
269*0b57cec5SDimitry Andric};
270*0b57cec5SDimitry Andric
271*0b57cec5SDimitry Andric
272*0b57cec5SDimitry Andrictemplate <class T>
273*0b57cec5SDimitry Andric    bool
274*0b57cec5SDimitry Andric    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
275*0b57cec5SDimitry Andric
276*0b57cec5SDimitry Andrictemplate <class T>
277*0b57cec5SDimitry Andric    bool
278*0b57cec5SDimitry Andric    atomic_is_lock_free(const atomic<T>* obj) noexcept;
279*0b57cec5SDimitry Andric
280*0b57cec5SDimitry Andrictemplate <class T>
281*0b57cec5SDimitry Andric    void
282*0b57cec5SDimitry Andric    atomic_init(volatile atomic<T>* obj, T desr) noexcept;
283*0b57cec5SDimitry Andric
284*0b57cec5SDimitry Andrictemplate <class T>
285*0b57cec5SDimitry Andric    void
286*0b57cec5SDimitry Andric    atomic_init(atomic<T>* obj, T desr) noexcept;
287*0b57cec5SDimitry Andric
288*0b57cec5SDimitry Andrictemplate <class T>
289*0b57cec5SDimitry Andric    void
290*0b57cec5SDimitry Andric    atomic_store(volatile atomic<T>* obj, T desr) noexcept;
291*0b57cec5SDimitry Andric
292*0b57cec5SDimitry Andrictemplate <class T>
293*0b57cec5SDimitry Andric    void
294*0b57cec5SDimitry Andric    atomic_store(atomic<T>* obj, T desr) noexcept;
295*0b57cec5SDimitry Andric
296*0b57cec5SDimitry Andrictemplate <class T>
297*0b57cec5SDimitry Andric    void
298*0b57cec5SDimitry Andric    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
299*0b57cec5SDimitry Andric
300*0b57cec5SDimitry Andrictemplate <class T>
301*0b57cec5SDimitry Andric    void
302*0b57cec5SDimitry Andric    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
303*0b57cec5SDimitry Andric
304*0b57cec5SDimitry Andrictemplate <class T>
305*0b57cec5SDimitry Andric    T
306*0b57cec5SDimitry Andric    atomic_load(const volatile atomic<T>* obj) noexcept;
307*0b57cec5SDimitry Andric
308*0b57cec5SDimitry Andrictemplate <class T>
309*0b57cec5SDimitry Andric    T
310*0b57cec5SDimitry Andric    atomic_load(const atomic<T>* obj) noexcept;
311*0b57cec5SDimitry Andric
312*0b57cec5SDimitry Andrictemplate <class T>
313*0b57cec5SDimitry Andric    T
314*0b57cec5SDimitry Andric    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
315*0b57cec5SDimitry Andric
316*0b57cec5SDimitry Andrictemplate <class T>
317*0b57cec5SDimitry Andric    T
318*0b57cec5SDimitry Andric    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
319*0b57cec5SDimitry Andric
320*0b57cec5SDimitry Andrictemplate <class T>
321*0b57cec5SDimitry Andric    T
322*0b57cec5SDimitry Andric    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
323*0b57cec5SDimitry Andric
324*0b57cec5SDimitry Andrictemplate <class T>
325*0b57cec5SDimitry Andric    T
326*0b57cec5SDimitry Andric    atomic_exchange(atomic<T>* obj, T desr) noexcept;
327*0b57cec5SDimitry Andric
328*0b57cec5SDimitry Andrictemplate <class T>
329*0b57cec5SDimitry Andric    T
330*0b57cec5SDimitry Andric    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
331*0b57cec5SDimitry Andric
332*0b57cec5SDimitry Andrictemplate <class T>
333*0b57cec5SDimitry Andric    T
334*0b57cec5SDimitry Andric    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
335*0b57cec5SDimitry Andric
336*0b57cec5SDimitry Andrictemplate <class T>
337*0b57cec5SDimitry Andric    bool
338*0b57cec5SDimitry Andric    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
339*0b57cec5SDimitry Andric
340*0b57cec5SDimitry Andrictemplate <class T>
341*0b57cec5SDimitry Andric    bool
342*0b57cec5SDimitry Andric    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
343*0b57cec5SDimitry Andric
344*0b57cec5SDimitry Andrictemplate <class T>
345*0b57cec5SDimitry Andric    bool
346*0b57cec5SDimitry Andric    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
347*0b57cec5SDimitry Andric
348*0b57cec5SDimitry Andrictemplate <class T>
349*0b57cec5SDimitry Andric    bool
350*0b57cec5SDimitry Andric    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
351*0b57cec5SDimitry Andric
352*0b57cec5SDimitry Andrictemplate <class T>
353*0b57cec5SDimitry Andric    bool
354*0b57cec5SDimitry Andric    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
355*0b57cec5SDimitry Andric                                          T desr,
356*0b57cec5SDimitry Andric                                          memory_order s, memory_order f) noexcept;
357*0b57cec5SDimitry Andric
358*0b57cec5SDimitry Andrictemplate <class T>
359*0b57cec5SDimitry Andric    bool
360*0b57cec5SDimitry Andric    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
361*0b57cec5SDimitry Andric                                          memory_order s, memory_order f) noexcept;
362*0b57cec5SDimitry Andric
363*0b57cec5SDimitry Andrictemplate <class T>
364*0b57cec5SDimitry Andric    bool
365*0b57cec5SDimitry Andric    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
366*0b57cec5SDimitry Andric                                            T* expc, T desr,
367*0b57cec5SDimitry Andric                                            memory_order s, memory_order f) noexcept;
368*0b57cec5SDimitry Andric
369*0b57cec5SDimitry Andrictemplate <class T>
370*0b57cec5SDimitry Andric    bool
371*0b57cec5SDimitry Andric    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
372*0b57cec5SDimitry Andric                                            T desr,
373*0b57cec5SDimitry Andric                                            memory_order s, memory_order f) noexcept;
374*0b57cec5SDimitry Andric
375*0b57cec5SDimitry Andrictemplate <class Integral>
376*0b57cec5SDimitry Andric    Integral
377*0b57cec5SDimitry Andric    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
378*0b57cec5SDimitry Andric
379*0b57cec5SDimitry Andrictemplate <class Integral>
380*0b57cec5SDimitry Andric    Integral
381*0b57cec5SDimitry Andric    atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
382*0b57cec5SDimitry Andric
383*0b57cec5SDimitry Andrictemplate <class Integral>
384*0b57cec5SDimitry Andric    Integral
385*0b57cec5SDimitry Andric    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
386*0b57cec5SDimitry Andric                              memory_order m) noexcept;
387*0b57cec5SDimitry Andrictemplate <class Integral>
388*0b57cec5SDimitry Andric    Integral
389*0b57cec5SDimitry Andric    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
390*0b57cec5SDimitry Andric                              memory_order m) noexcept;
391*0b57cec5SDimitry Andrictemplate <class Integral>
392*0b57cec5SDimitry Andric    Integral
393*0b57cec5SDimitry Andric    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
394*0b57cec5SDimitry Andric
395*0b57cec5SDimitry Andrictemplate <class Integral>
396*0b57cec5SDimitry Andric    Integral
397*0b57cec5SDimitry Andric    atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
398*0b57cec5SDimitry Andric
399*0b57cec5SDimitry Andrictemplate <class Integral>
400*0b57cec5SDimitry Andric    Integral
401*0b57cec5SDimitry Andric    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
402*0b57cec5SDimitry Andric                              memory_order m) noexcept;
403*0b57cec5SDimitry Andrictemplate <class Integral>
404*0b57cec5SDimitry Andric    Integral
405*0b57cec5SDimitry Andric    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
406*0b57cec5SDimitry Andric                              memory_order m) noexcept;
407*0b57cec5SDimitry Andrictemplate <class Integral>
408*0b57cec5SDimitry Andric    Integral
409*0b57cec5SDimitry Andric    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
410*0b57cec5SDimitry Andric
411*0b57cec5SDimitry Andrictemplate <class Integral>
412*0b57cec5SDimitry Andric    Integral
413*0b57cec5SDimitry Andric    atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
414*0b57cec5SDimitry Andric
415*0b57cec5SDimitry Andrictemplate <class Integral>
416*0b57cec5SDimitry Andric    Integral
417*0b57cec5SDimitry Andric    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
418*0b57cec5SDimitry Andric                              memory_order m) noexcept;
419*0b57cec5SDimitry Andrictemplate <class Integral>
420*0b57cec5SDimitry Andric    Integral
421*0b57cec5SDimitry Andric    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
422*0b57cec5SDimitry Andric                              memory_order m) noexcept;
423*0b57cec5SDimitry Andrictemplate <class Integral>
424*0b57cec5SDimitry Andric    Integral
425*0b57cec5SDimitry Andric    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
426*0b57cec5SDimitry Andric
427*0b57cec5SDimitry Andrictemplate <class Integral>
428*0b57cec5SDimitry Andric    Integral
429*0b57cec5SDimitry Andric    atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
430*0b57cec5SDimitry Andric
431*0b57cec5SDimitry Andrictemplate <class Integral>
432*0b57cec5SDimitry Andric    Integral
433*0b57cec5SDimitry Andric    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
434*0b57cec5SDimitry Andric                             memory_order m) noexcept;
435*0b57cec5SDimitry Andrictemplate <class Integral>
436*0b57cec5SDimitry Andric    Integral
437*0b57cec5SDimitry Andric    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
438*0b57cec5SDimitry Andric                             memory_order m) noexcept;
439*0b57cec5SDimitry Andrictemplate <class Integral>
440*0b57cec5SDimitry Andric    Integral
441*0b57cec5SDimitry Andric    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
442*0b57cec5SDimitry Andric
443*0b57cec5SDimitry Andrictemplate <class Integral>
444*0b57cec5SDimitry Andric    Integral
445*0b57cec5SDimitry Andric    atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
446*0b57cec5SDimitry Andric
447*0b57cec5SDimitry Andrictemplate <class Integral>
448*0b57cec5SDimitry Andric    Integral
449*0b57cec5SDimitry Andric    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
450*0b57cec5SDimitry Andric                              memory_order m) noexcept;
451*0b57cec5SDimitry Andrictemplate <class Integral>
452*0b57cec5SDimitry Andric    Integral
453*0b57cec5SDimitry Andric    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
454*0b57cec5SDimitry Andric                              memory_order m) noexcept;
455*0b57cec5SDimitry Andric
456*0b57cec5SDimitry Andrictemplate <class T>
457*0b57cec5SDimitry Andric    T*
458*0b57cec5SDimitry Andric    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
459*0b57cec5SDimitry Andric
460*0b57cec5SDimitry Andrictemplate <class T>
461*0b57cec5SDimitry Andric    T*
462*0b57cec5SDimitry Andric    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
463*0b57cec5SDimitry Andric
464*0b57cec5SDimitry Andrictemplate <class T>
465*0b57cec5SDimitry Andric    T*
466*0b57cec5SDimitry Andric    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
467*0b57cec5SDimitry Andric                              memory_order m) noexcept;
468*0b57cec5SDimitry Andrictemplate <class T>
469*0b57cec5SDimitry Andric    T*
470*0b57cec5SDimitry Andric    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
471*0b57cec5SDimitry Andric
472*0b57cec5SDimitry Andrictemplate <class T>
473*0b57cec5SDimitry Andric    T*
474*0b57cec5SDimitry Andric    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
475*0b57cec5SDimitry Andric
476*0b57cec5SDimitry Andrictemplate <class T>
477*0b57cec5SDimitry Andric    T*
478*0b57cec5SDimitry Andric    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
479*0b57cec5SDimitry Andric
480*0b57cec5SDimitry Andrictemplate <class T>
481*0b57cec5SDimitry Andric    T*
482*0b57cec5SDimitry Andric    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
483*0b57cec5SDimitry Andric                              memory_order m) noexcept;
484*0b57cec5SDimitry Andrictemplate <class T>
485*0b57cec5SDimitry Andric    T*
486*0b57cec5SDimitry Andric    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
487*0b57cec5SDimitry Andric
488*0b57cec5SDimitry Andric// Atomics for standard typedef types
489*0b57cec5SDimitry Andric
490*0b57cec5SDimitry Andrictypedef atomic<bool>               atomic_bool;
491*0b57cec5SDimitry Andrictypedef atomic<char>               atomic_char;
492*0b57cec5SDimitry Andrictypedef atomic<signed char>        atomic_schar;
493*0b57cec5SDimitry Andrictypedef atomic<unsigned char>      atomic_uchar;
494*0b57cec5SDimitry Andrictypedef atomic<short>              atomic_short;
495*0b57cec5SDimitry Andrictypedef atomic<unsigned short>     atomic_ushort;
496*0b57cec5SDimitry Andrictypedef atomic<int>                atomic_int;
497*0b57cec5SDimitry Andrictypedef atomic<unsigned int>       atomic_uint;
498*0b57cec5SDimitry Andrictypedef atomic<long>               atomic_long;
499*0b57cec5SDimitry Andrictypedef atomic<unsigned long>      atomic_ulong;
500*0b57cec5SDimitry Andrictypedef atomic<long long>          atomic_llong;
501*0b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong;
502*0b57cec5SDimitry Andrictypedef atomic<char16_t>           atomic_char16_t;
503*0b57cec5SDimitry Andrictypedef atomic<char32_t>           atomic_char32_t;
504*0b57cec5SDimitry Andrictypedef atomic<wchar_t>            atomic_wchar_t;
505*0b57cec5SDimitry Andric
506*0b57cec5SDimitry Andrictypedef atomic<int_least8_t>   atomic_int_least8_t;
507*0b57cec5SDimitry Andrictypedef atomic<uint_least8_t>  atomic_uint_least8_t;
508*0b57cec5SDimitry Andrictypedef atomic<int_least16_t>  atomic_int_least16_t;
509*0b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t;
510*0b57cec5SDimitry Andrictypedef atomic<int_least32_t>  atomic_int_least32_t;
511*0b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t;
512*0b57cec5SDimitry Andrictypedef atomic<int_least64_t>  atomic_int_least64_t;
513*0b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t;
514*0b57cec5SDimitry Andric
515*0b57cec5SDimitry Andrictypedef atomic<int_fast8_t>   atomic_int_fast8_t;
516*0b57cec5SDimitry Andrictypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
517*0b57cec5SDimitry Andrictypedef atomic<int_fast16_t>  atomic_int_fast16_t;
518*0b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
519*0b57cec5SDimitry Andrictypedef atomic<int_fast32_t>  atomic_int_fast32_t;
520*0b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
521*0b57cec5SDimitry Andrictypedef atomic<int_fast64_t>  atomic_int_fast64_t;
522*0b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
523*0b57cec5SDimitry Andric
524*0b57cec5SDimitry Andrictypedef atomic<int8_t>   atomic_int8_t;
525*0b57cec5SDimitry Andrictypedef atomic<uint8_t>  atomic_uint8_t;
526*0b57cec5SDimitry Andrictypedef atomic<int16_t>  atomic_int16_t;
527*0b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t;
528*0b57cec5SDimitry Andrictypedef atomic<int32_t>  atomic_int32_t;
529*0b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t;
530*0b57cec5SDimitry Andrictypedef atomic<int64_t>  atomic_int64_t;
531*0b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t;
532*0b57cec5SDimitry Andric
533*0b57cec5SDimitry Andrictypedef atomic<intptr_t>  atomic_intptr_t;
534*0b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t;
535*0b57cec5SDimitry Andrictypedef atomic<size_t>    atomic_size_t;
536*0b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
537*0b57cec5SDimitry Andrictypedef atomic<intmax_t>  atomic_intmax_t;
538*0b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t;
539*0b57cec5SDimitry Andric
540*0b57cec5SDimitry Andric// fences
541*0b57cec5SDimitry Andric
542*0b57cec5SDimitry Andricvoid atomic_thread_fence(memory_order m) noexcept;
543*0b57cec5SDimitry Andricvoid atomic_signal_fence(memory_order m) noexcept;
544*0b57cec5SDimitry Andric
545*0b57cec5SDimitry Andric}  // std
546*0b57cec5SDimitry Andric
547*0b57cec5SDimitry Andric*/
548*0b57cec5SDimitry Andric
549*0b57cec5SDimitry Andric#include <__config>
550*0b57cec5SDimitry Andric#include <cstddef>
551*0b57cec5SDimitry Andric#include <cstdint>
552*0b57cec5SDimitry Andric#include <type_traits>
553*0b57cec5SDimitry Andric#include <version>
554*0b57cec5SDimitry Andric
555*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
556*0b57cec5SDimitry Andric#pragma GCC system_header
557*0b57cec5SDimitry Andric#endif
558*0b57cec5SDimitry Andric
559*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
560*0b57cec5SDimitry Andric# error <atomic> is not supported on this single threaded system
561*0b57cec5SDimitry Andric#endif
562*0b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
563*0b57cec5SDimitry Andric# error <atomic> is not implemented
564*0b57cec5SDimitry Andric#endif
565*0b57cec5SDimitry Andric#ifdef kill_dependency
566*0b57cec5SDimitry Andric# error C++ standard library is incompatible with <stdatomic.h>
567*0b57cec5SDimitry Andric#endif
568*0b57cec5SDimitry Andric
569*0b57cec5SDimitry Andric#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
570*0b57cec5SDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
571*0b57cec5SDimitry Andric                           __m == memory_order_acquire || \
572*0b57cec5SDimitry Andric                           __m == memory_order_acq_rel,   \
573*0b57cec5SDimitry Andric                        "memory order argument to atomic operation is invalid")
574*0b57cec5SDimitry Andric
575*0b57cec5SDimitry Andric#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
576*0b57cec5SDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
577*0b57cec5SDimitry Andric                           __m == memory_order_acq_rel,   \
578*0b57cec5SDimitry Andric                        "memory order argument to atomic operation is invalid")
579*0b57cec5SDimitry Andric
580*0b57cec5SDimitry Andric#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
581*0b57cec5SDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
582*0b57cec5SDimitry Andric                           __f == memory_order_acq_rel,   \
583*0b57cec5SDimitry Andric                        "memory order argument to atomic operation is invalid")
584*0b57cec5SDimitry Andric
585*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
586*0b57cec5SDimitry Andric
587*0b57cec5SDimitry Andric// Figure out what the underlying type for `memory_order` would be if it were
588*0b57cec5SDimitry Andric// declared as an unscoped enum (accounting for -fshort-enums). Use this result
589*0b57cec5SDimitry Andric// to pin the underlying type in C++20.
590*0b57cec5SDimitry Andricenum __legacy_memory_order {
591*0b57cec5SDimitry Andric    __mo_relaxed,
592*0b57cec5SDimitry Andric    __mo_consume,
593*0b57cec5SDimitry Andric    __mo_acquire,
594*0b57cec5SDimitry Andric    __mo_release,
595*0b57cec5SDimitry Andric    __mo_acq_rel,
596*0b57cec5SDimitry Andric    __mo_seq_cst
597*0b57cec5SDimitry Andric};
598*0b57cec5SDimitry Andric
599*0b57cec5SDimitry Andrictypedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
600*0b57cec5SDimitry Andric
601*0b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17
602*0b57cec5SDimitry Andric
603*0b57cec5SDimitry Andricenum class memory_order : __memory_order_underlying_t {
604*0b57cec5SDimitry Andric  relaxed = __mo_relaxed,
605*0b57cec5SDimitry Andric  consume = __mo_consume,
606*0b57cec5SDimitry Andric  acquire = __mo_acquire,
607*0b57cec5SDimitry Andric  release = __mo_release,
608*0b57cec5SDimitry Andric  acq_rel = __mo_acq_rel,
609*0b57cec5SDimitry Andric  seq_cst = __mo_seq_cst
610*0b57cec5SDimitry Andric};
611*0b57cec5SDimitry Andric
612*0b57cec5SDimitry Andricinline constexpr auto memory_order_relaxed = memory_order::relaxed;
613*0b57cec5SDimitry Andricinline constexpr auto memory_order_consume = memory_order::consume;
614*0b57cec5SDimitry Andricinline constexpr auto memory_order_acquire = memory_order::acquire;
615*0b57cec5SDimitry Andricinline constexpr auto memory_order_release = memory_order::release;
616*0b57cec5SDimitry Andricinline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
617*0b57cec5SDimitry Andricinline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
618*0b57cec5SDimitry Andric
619*0b57cec5SDimitry Andric#else
620*0b57cec5SDimitry Andric
621*0b57cec5SDimitry Andrictypedef enum memory_order {
622*0b57cec5SDimitry Andric  memory_order_relaxed = __mo_relaxed,
623*0b57cec5SDimitry Andric  memory_order_consume = __mo_consume,
624*0b57cec5SDimitry Andric  memory_order_acquire = __mo_acquire,
625*0b57cec5SDimitry Andric  memory_order_release = __mo_release,
626*0b57cec5SDimitry Andric  memory_order_acq_rel = __mo_acq_rel,
627*0b57cec5SDimitry Andric  memory_order_seq_cst = __mo_seq_cst,
628*0b57cec5SDimitry Andric} memory_order;
629*0b57cec5SDimitry Andric
630*0b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 17
631*0b57cec5SDimitry Andric
632*0b57cec5SDimitry Andricstatic_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
633*0b57cec5SDimitry Andric  "unexpected underlying type for std::memory_order");
634*0b57cec5SDimitry Andric
635*0b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
636*0b57cec5SDimitry Andric	defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
637*0b57cec5SDimitry Andric
638*0b57cec5SDimitry Andric// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
639*0b57cec5SDimitry Andric// the default operator= in an object is not volatile, a byte-by-byte copy
640*0b57cec5SDimitry Andric// is required.
641*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
642*0b57cec5SDimitry Andrictypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
643*0b57cec5SDimitry Andric__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
644*0b57cec5SDimitry Andric  __a_value = __val;
645*0b57cec5SDimitry Andric}
646*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
647*0b57cec5SDimitry Andrictypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
648*0b57cec5SDimitry Andric__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
649*0b57cec5SDimitry Andric  volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
650*0b57cec5SDimitry Andric  volatile char* __end = __to + sizeof(_Tp);
651*0b57cec5SDimitry Andric  volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
652*0b57cec5SDimitry Andric  while (__to != __end)
653*0b57cec5SDimitry Andric    *__to++ = *__from++;
654*0b57cec5SDimitry Andric}
655*0b57cec5SDimitry Andric
656*0b57cec5SDimitry Andric#endif
657*0b57cec5SDimitry Andric
658*0b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
659*0b57cec5SDimitry Andric
660*0b57cec5SDimitry Andrictemplate <typename _Tp>
661*0b57cec5SDimitry Andricstruct __cxx_atomic_base_impl {
662*0b57cec5SDimitry Andric
663*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
664*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
665*0b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT = default;
666*0b57cec5SDimitry Andric#else
667*0b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
668*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
669*0b57cec5SDimitry Andric  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
670*0b57cec5SDimitry Andric    : __a_value(value) {}
671*0b57cec5SDimitry Andric  _Tp __a_value;
672*0b57cec5SDimitry Andric};
673*0b57cec5SDimitry Andric
674*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
675*0b57cec5SDimitry Andric  // Avoid switch statement to make this a constexpr.
676*0b57cec5SDimitry Andric  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
677*0b57cec5SDimitry Andric         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
678*0b57cec5SDimitry Andric          (__order == memory_order_release ? __ATOMIC_RELEASE:
679*0b57cec5SDimitry Andric           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
680*0b57cec5SDimitry Andric            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
681*0b57cec5SDimitry Andric              __ATOMIC_CONSUME))));
682*0b57cec5SDimitry Andric}
683*0b57cec5SDimitry Andric
684*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
685*0b57cec5SDimitry Andric  // Avoid switch statement to make this a constexpr.
686*0b57cec5SDimitry Andric  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
687*0b57cec5SDimitry Andric         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
688*0b57cec5SDimitry Andric          (__order == memory_order_release ? __ATOMIC_RELAXED:
689*0b57cec5SDimitry Andric           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
690*0b57cec5SDimitry Andric            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
691*0b57cec5SDimitry Andric              __ATOMIC_CONSUME))));
692*0b57cec5SDimitry Andric}
693*0b57cec5SDimitry Andric
694*0b57cec5SDimitry Andrictemplate <typename _Tp>
695*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
696*0b57cec5SDimitry Andricvoid __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
697*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __val);
698*0b57cec5SDimitry Andric}
699*0b57cec5SDimitry Andric
700*0b57cec5SDimitry Andrictemplate <typename _Tp>
701*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
702*0b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
703*0b57cec5SDimitry Andric  __a->__a_value = __val;
704*0b57cec5SDimitry Andric}
705*0b57cec5SDimitry Andric
706*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
707*0b57cec5SDimitry Andricvoid __cxx_atomic_thread_fence(memory_order __order) {
708*0b57cec5SDimitry Andric  __atomic_thread_fence(__to_gcc_order(__order));
709*0b57cec5SDimitry Andric}
710*0b57cec5SDimitry Andric
711*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
712*0b57cec5SDimitry Andricvoid __cxx_atomic_signal_fence(memory_order __order) {
713*0b57cec5SDimitry Andric  __atomic_signal_fence(__to_gcc_order(__order));
714*0b57cec5SDimitry Andric}
715*0b57cec5SDimitry Andric
716*0b57cec5SDimitry Andrictemplate <typename _Tp>
717*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
718*0b57cec5SDimitry Andricvoid __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
719*0b57cec5SDimitry Andric                        memory_order __order) {
720*0b57cec5SDimitry Andric  __atomic_store(&__a->__a_value, &__val,
721*0b57cec5SDimitry Andric                 __to_gcc_order(__order));
722*0b57cec5SDimitry Andric}
723*0b57cec5SDimitry Andric
724*0b57cec5SDimitry Andrictemplate <typename _Tp>
725*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
726*0b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
727*0b57cec5SDimitry Andric                        memory_order __order) {
728*0b57cec5SDimitry Andric  __atomic_store(&__a->__a_value, &__val,
729*0b57cec5SDimitry Andric                 __to_gcc_order(__order));
730*0b57cec5SDimitry Andric}
731*0b57cec5SDimitry Andric
732*0b57cec5SDimitry Andrictemplate <typename _Tp>
733*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
734*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
735*0b57cec5SDimitry Andric                      memory_order __order) {
736*0b57cec5SDimitry Andric  _Tp __ret;
737*0b57cec5SDimitry Andric  __atomic_load(&__a->__a_value, &__ret,
738*0b57cec5SDimitry Andric                __to_gcc_order(__order));
739*0b57cec5SDimitry Andric  return __ret;
740*0b57cec5SDimitry Andric}
741*0b57cec5SDimitry Andric
742*0b57cec5SDimitry Andrictemplate <typename _Tp>
743*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
744*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
745*0b57cec5SDimitry Andric  _Tp __ret;
746*0b57cec5SDimitry Andric  __atomic_load(&__a->__a_value, &__ret,
747*0b57cec5SDimitry Andric                __to_gcc_order(__order));
748*0b57cec5SDimitry Andric  return __ret;
749*0b57cec5SDimitry Andric}
750*0b57cec5SDimitry Andric
751*0b57cec5SDimitry Andrictemplate <typename _Tp>
752*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
753*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
754*0b57cec5SDimitry Andric                          _Tp __value, memory_order __order) {
755*0b57cec5SDimitry Andric  _Tp __ret;
756*0b57cec5SDimitry Andric  __atomic_exchange(&__a->__a_value, &__value, &__ret,
757*0b57cec5SDimitry Andric                    __to_gcc_order(__order));
758*0b57cec5SDimitry Andric  return __ret;
759*0b57cec5SDimitry Andric}
760*0b57cec5SDimitry Andric
761*0b57cec5SDimitry Andrictemplate <typename _Tp>
762*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
763*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
764*0b57cec5SDimitry Andric                          memory_order __order) {
765*0b57cec5SDimitry Andric  _Tp __ret;
766*0b57cec5SDimitry Andric  __atomic_exchange(&__a->__a_value, &__value, &__ret,
767*0b57cec5SDimitry Andric                    __to_gcc_order(__order));
768*0b57cec5SDimitry Andric  return __ret;
769*0b57cec5SDimitry Andric}
770*0b57cec5SDimitry Andric
771*0b57cec5SDimitry Andrictemplate <typename _Tp>
772*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
773*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(
774*0b57cec5SDimitry Andric    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
775*0b57cec5SDimitry Andric    memory_order __success, memory_order __failure) {
776*0b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
777*0b57cec5SDimitry Andric                                   false,
778*0b57cec5SDimitry Andric                                   __to_gcc_order(__success),
779*0b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
780*0b57cec5SDimitry Andric}
781*0b57cec5SDimitry Andric
782*0b57cec5SDimitry Andrictemplate <typename _Tp>
783*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
784*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(
785*0b57cec5SDimitry Andric    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
786*0b57cec5SDimitry Andric    memory_order __failure) {
787*0b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
788*0b57cec5SDimitry Andric                                   false,
789*0b57cec5SDimitry Andric                                   __to_gcc_order(__success),
790*0b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
791*0b57cec5SDimitry Andric}
792*0b57cec5SDimitry Andric
793*0b57cec5SDimitry Andrictemplate <typename _Tp>
794*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
795*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(
796*0b57cec5SDimitry Andric    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
797*0b57cec5SDimitry Andric    memory_order __success, memory_order __failure) {
798*0b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
799*0b57cec5SDimitry Andric                                   true,
800*0b57cec5SDimitry Andric                                   __to_gcc_order(__success),
801*0b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
802*0b57cec5SDimitry Andric}
803*0b57cec5SDimitry Andric
804*0b57cec5SDimitry Andrictemplate <typename _Tp>
805*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
806*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(
807*0b57cec5SDimitry Andric    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
808*0b57cec5SDimitry Andric    memory_order __failure) {
809*0b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
810*0b57cec5SDimitry Andric                                   true,
811*0b57cec5SDimitry Andric                                   __to_gcc_order(__success),
812*0b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
813*0b57cec5SDimitry Andric}
814*0b57cec5SDimitry Andric
815*0b57cec5SDimitry Andrictemplate <typename _Tp>
816*0b57cec5SDimitry Andricstruct __skip_amt { enum {value = 1}; };
817*0b57cec5SDimitry Andric
818*0b57cec5SDimitry Andrictemplate <typename _Tp>
819*0b57cec5SDimitry Andricstruct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
820*0b57cec5SDimitry Andric
821*0b57cec5SDimitry Andric// FIXME: Haven't figured out what the spec says about using arrays with
822*0b57cec5SDimitry Andric// atomic_fetch_add. Force a failure rather than creating bad behavior.
823*0b57cec5SDimitry Andrictemplate <typename _Tp>
824*0b57cec5SDimitry Andricstruct __skip_amt<_Tp[]> { };
825*0b57cec5SDimitry Andrictemplate <typename _Tp, int n>
826*0b57cec5SDimitry Andricstruct __skip_amt<_Tp[n]> { };
827*0b57cec5SDimitry Andric
828*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
829*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
830*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
831*0b57cec5SDimitry Andric                           _Td __delta, memory_order __order) {
832*0b57cec5SDimitry Andric  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
833*0b57cec5SDimitry Andric                            __to_gcc_order(__order));
834*0b57cec5SDimitry Andric}
835*0b57cec5SDimitry Andric
836*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
837*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
838*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
839*0b57cec5SDimitry Andric                           memory_order __order) {
840*0b57cec5SDimitry Andric  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
841*0b57cec5SDimitry Andric                            __to_gcc_order(__order));
842*0b57cec5SDimitry Andric}
843*0b57cec5SDimitry Andric
844*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
845*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
846*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
847*0b57cec5SDimitry Andric                           _Td __delta, memory_order __order) {
848*0b57cec5SDimitry Andric  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
849*0b57cec5SDimitry Andric                            __to_gcc_order(__order));
850*0b57cec5SDimitry Andric}
851*0b57cec5SDimitry Andric
852*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
853*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
854*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
855*0b57cec5SDimitry Andric                           memory_order __order) {
856*0b57cec5SDimitry Andric  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
857*0b57cec5SDimitry Andric                            __to_gcc_order(__order));
858*0b57cec5SDimitry Andric}
859*0b57cec5SDimitry Andric
860*0b57cec5SDimitry Andrictemplate <typename _Tp>
861*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
862*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
863*0b57cec5SDimitry Andric                           _Tp __pattern, memory_order __order) {
864*0b57cec5SDimitry Andric  return __atomic_fetch_and(&__a->__a_value, __pattern,
865*0b57cec5SDimitry Andric                            __to_gcc_order(__order));
866*0b57cec5SDimitry Andric}
867*0b57cec5SDimitry Andric
868*0b57cec5SDimitry Andrictemplate <typename _Tp>
869*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
870*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
871*0b57cec5SDimitry Andric                           _Tp __pattern, memory_order __order) {
872*0b57cec5SDimitry Andric  return __atomic_fetch_and(&__a->__a_value, __pattern,
873*0b57cec5SDimitry Andric                            __to_gcc_order(__order));
874*0b57cec5SDimitry Andric}
875*0b57cec5SDimitry Andric
876*0b57cec5SDimitry Andrictemplate <typename _Tp>
877*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
878*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
879*0b57cec5SDimitry Andric                          _Tp __pattern, memory_order __order) {
880*0b57cec5SDimitry Andric  return __atomic_fetch_or(&__a->__a_value, __pattern,
881*0b57cec5SDimitry Andric                           __to_gcc_order(__order));
882*0b57cec5SDimitry Andric}
883*0b57cec5SDimitry Andric
884*0b57cec5SDimitry Andrictemplate <typename _Tp>
885*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
886*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
887*0b57cec5SDimitry Andric                          memory_order __order) {
888*0b57cec5SDimitry Andric  return __atomic_fetch_or(&__a->__a_value, __pattern,
889*0b57cec5SDimitry Andric                           __to_gcc_order(__order));
890*0b57cec5SDimitry Andric}
891*0b57cec5SDimitry Andric
892*0b57cec5SDimitry Andrictemplate <typename _Tp>
893*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
894*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
895*0b57cec5SDimitry Andric                           _Tp __pattern, memory_order __order) {
896*0b57cec5SDimitry Andric  return __atomic_fetch_xor(&__a->__a_value, __pattern,
897*0b57cec5SDimitry Andric                            __to_gcc_order(__order));
898*0b57cec5SDimitry Andric}
899*0b57cec5SDimitry Andric
900*0b57cec5SDimitry Andrictemplate <typename _Tp>
901*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
902*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
903*0b57cec5SDimitry Andric                           memory_order __order) {
904*0b57cec5SDimitry Andric  return __atomic_fetch_xor(&__a->__a_value, __pattern,
905*0b57cec5SDimitry Andric                            __to_gcc_order(__order));
906*0b57cec5SDimitry Andric}
907*0b57cec5SDimitry Andric
908*0b57cec5SDimitry Andric#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
909*0b57cec5SDimitry Andric
910*0b57cec5SDimitry Andric#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
911*0b57cec5SDimitry Andric
912*0b57cec5SDimitry Andrictemplate <typename _Tp>
913*0b57cec5SDimitry Andricstruct __cxx_atomic_base_impl {
914*0b57cec5SDimitry Andric
915*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
916*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
917*0b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT = default;
918*0b57cec5SDimitry Andric#else
919*0b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
920*0b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
921*0b57cec5SDimitry Andric  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
922*0b57cec5SDimitry Andric    : __a_value(value) {}
923*0b57cec5SDimitry Andric  _Atomic(_Tp) __a_value;
924*0b57cec5SDimitry Andric};
925*0b57cec5SDimitry Andric
926*0b57cec5SDimitry Andric#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
927*0b57cec5SDimitry Andric
928*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
929*0b57cec5SDimitry Andricvoid __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
930*0b57cec5SDimitry Andric    __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
931*0b57cec5SDimitry Andric}
932*0b57cec5SDimitry Andric
933*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
934*0b57cec5SDimitry Andricvoid __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
935*0b57cec5SDimitry Andric    __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
936*0b57cec5SDimitry Andric}
937*0b57cec5SDimitry Andric
938*0b57cec5SDimitry Andrictemplate<class _Tp>
939*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
940*0b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
941*0b57cec5SDimitry Andric    __c11_atomic_init(&__a->__a_value, __val);
942*0b57cec5SDimitry Andric}
943*0b57cec5SDimitry Andrictemplate<class _Tp>
944*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
945*0b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
946*0b57cec5SDimitry Andric    __c11_atomic_init(&__a->__a_value, __val);
947*0b57cec5SDimitry Andric}
948*0b57cec5SDimitry Andric
949*0b57cec5SDimitry Andrictemplate<class _Tp>
950*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
951*0b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
952*0b57cec5SDimitry Andric    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
953*0b57cec5SDimitry Andric}
954*0b57cec5SDimitry Andrictemplate<class _Tp>
955*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
956*0b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
957*0b57cec5SDimitry Andric    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
958*0b57cec5SDimitry Andric}
959*0b57cec5SDimitry Andric
960*0b57cec5SDimitry Andrictemplate<class _Tp>
961*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
962*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
963*0b57cec5SDimitry Andric    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
964*0b57cec5SDimitry Andric    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
965*0b57cec5SDimitry Andric}
966*0b57cec5SDimitry Andrictemplate<class _Tp>
967*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
968*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
969*0b57cec5SDimitry Andric    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
970*0b57cec5SDimitry Andric    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
971*0b57cec5SDimitry Andric}
972*0b57cec5SDimitry Andric
973*0b57cec5SDimitry Andrictemplate<class _Tp>
974*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
975*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
976*0b57cec5SDimitry Andric    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
977*0b57cec5SDimitry Andric}
978*0b57cec5SDimitry Andrictemplate<class _Tp>
979*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
980*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
981*0b57cec5SDimitry Andric    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
982*0b57cec5SDimitry Andric}
983*0b57cec5SDimitry Andric
984*0b57cec5SDimitry Andrictemplate<class _Tp>
985*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
986*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
987*0b57cec5SDimitry Andric    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
988*0b57cec5SDimitry Andric}
989*0b57cec5SDimitry Andrictemplate<class _Tp>
990*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
991*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
992*0b57cec5SDimitry Andric    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
993*0b57cec5SDimitry Andric}
994*0b57cec5SDimitry Andric
995*0b57cec5SDimitry Andrictemplate<class _Tp>
996*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
997*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
998*0b57cec5SDimitry Andric    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
999*0b57cec5SDimitry Andric}
1000*0b57cec5SDimitry Andrictemplate<class _Tp>
1001*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1002*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
1003*0b57cec5SDimitry Andric    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value,  static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
1004*0b57cec5SDimitry Andric}
1005*0b57cec5SDimitry Andric
1006*0b57cec5SDimitry Andrictemplate<class _Tp>
1007*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1008*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
1009*0b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1010*0b57cec5SDimitry Andric}
1011*0b57cec5SDimitry Andrictemplate<class _Tp>
1012*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1013*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
1014*0b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1015*0b57cec5SDimitry Andric}
1016*0b57cec5SDimitry Andric
1017*0b57cec5SDimitry Andrictemplate<class _Tp>
1018*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1019*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
1020*0b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1021*0b57cec5SDimitry Andric}
1022*0b57cec5SDimitry Andrictemplate<class _Tp>
1023*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1024*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
1025*0b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1026*0b57cec5SDimitry Andric}
1027*0b57cec5SDimitry Andric
1028*0b57cec5SDimitry Andrictemplate<class _Tp>
1029*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1030*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
1031*0b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1032*0b57cec5SDimitry Andric}
1033*0b57cec5SDimitry Andrictemplate<class _Tp>
1034*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1035*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
1036*0b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1037*0b57cec5SDimitry Andric}
1038*0b57cec5SDimitry Andrictemplate<class _Tp>
1039*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1040*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
1041*0b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1042*0b57cec5SDimitry Andric}
1043*0b57cec5SDimitry Andrictemplate<class _Tp>
1044*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1045*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
1046*0b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
1047*0b57cec5SDimitry Andric}
1048*0b57cec5SDimitry Andric
1049*0b57cec5SDimitry Andrictemplate<class _Tp>
1050*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1051*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1052*0b57cec5SDimitry Andric    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1053*0b57cec5SDimitry Andric}
1054*0b57cec5SDimitry Andrictemplate<class _Tp>
1055*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1056*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1057*0b57cec5SDimitry Andric    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1058*0b57cec5SDimitry Andric}
1059*0b57cec5SDimitry Andric
1060*0b57cec5SDimitry Andrictemplate<class _Tp>
1061*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1062*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1063*0b57cec5SDimitry Andric    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1064*0b57cec5SDimitry Andric}
1065*0b57cec5SDimitry Andrictemplate<class _Tp>
1066*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1067*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1068*0b57cec5SDimitry Andric    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1069*0b57cec5SDimitry Andric}
1070*0b57cec5SDimitry Andric
1071*0b57cec5SDimitry Andrictemplate<class _Tp>
1072*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1073*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1074*0b57cec5SDimitry Andric    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1075*0b57cec5SDimitry Andric}
1076*0b57cec5SDimitry Andrictemplate<class _Tp>
1077*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1078*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
1079*0b57cec5SDimitry Andric    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
1080*0b57cec5SDimitry Andric}
1081*0b57cec5SDimitry Andric
1082*0b57cec5SDimitry Andric#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
1083*0b57cec5SDimitry Andric
1084*0b57cec5SDimitry Andrictemplate <class _Tp>
1085*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1086*0b57cec5SDimitry Andric_Tp kill_dependency(_Tp __y) _NOEXCEPT
1087*0b57cec5SDimitry Andric{
1088*0b57cec5SDimitry Andric    return __y;
1089*0b57cec5SDimitry Andric}
1090*0b57cec5SDimitry Andric
1091*0b57cec5SDimitry Andric#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
1092*0b57cec5SDimitry Andric# define ATOMIC_BOOL_LOCK_FREE      __CLANG_ATOMIC_BOOL_LOCK_FREE
1093*0b57cec5SDimitry Andric# define ATOMIC_CHAR_LOCK_FREE      __CLANG_ATOMIC_CHAR_LOCK_FREE
1094*0b57cec5SDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE  __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
1095*0b57cec5SDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE  __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
1096*0b57cec5SDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE   __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
1097*0b57cec5SDimitry Andric# define ATOMIC_SHORT_LOCK_FREE     __CLANG_ATOMIC_SHORT_LOCK_FREE
1098*0b57cec5SDimitry Andric# define ATOMIC_INT_LOCK_FREE       __CLANG_ATOMIC_INT_LOCK_FREE
1099*0b57cec5SDimitry Andric# define ATOMIC_LONG_LOCK_FREE      __CLANG_ATOMIC_LONG_LOCK_FREE
1100*0b57cec5SDimitry Andric# define ATOMIC_LLONG_LOCK_FREE     __CLANG_ATOMIC_LLONG_LOCK_FREE
1101*0b57cec5SDimitry Andric# define ATOMIC_POINTER_LOCK_FREE   __CLANG_ATOMIC_POINTER_LOCK_FREE
1102*0b57cec5SDimitry Andric#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
1103*0b57cec5SDimitry Andric# define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
1104*0b57cec5SDimitry Andric# define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
1105*0b57cec5SDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
1106*0b57cec5SDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
1107*0b57cec5SDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
1108*0b57cec5SDimitry Andric# define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
1109*0b57cec5SDimitry Andric# define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
1110*0b57cec5SDimitry Andric# define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
1111*0b57cec5SDimitry Andric# define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
1112*0b57cec5SDimitry Andric# define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
1113*0b57cec5SDimitry Andric#endif
1114*0b57cec5SDimitry Andric
1115*0b57cec5SDimitry Andric#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1116*0b57cec5SDimitry Andric
1117*0b57cec5SDimitry Andrictemplate<typename _Tp>
1118*0b57cec5SDimitry Andricstruct __cxx_atomic_lock_impl {
1119*0b57cec5SDimitry Andric
1120*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
1121*0b57cec5SDimitry Andric  __cxx_atomic_lock_impl() _NOEXCEPT
1122*0b57cec5SDimitry Andric    : __a_value(), __a_lock(0) {}
1123*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
1124*0b57cec5SDimitry Andric  __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
1125*0b57cec5SDimitry Andric    : __a_value(value), __a_lock(0) {}
1126*0b57cec5SDimitry Andric
1127*0b57cec5SDimitry Andric  _Tp __a_value;
1128*0b57cec5SDimitry Andric  mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
1129*0b57cec5SDimitry Andric
1130*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
1131*0b57cec5SDimitry Andric    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1132*0b57cec5SDimitry Andric        /*spin*/;
1133*0b57cec5SDimitry Andric  }
1134*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __lock() const {
1135*0b57cec5SDimitry Andric    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
1136*0b57cec5SDimitry Andric        /*spin*/;
1137*0b57cec5SDimitry Andric  }
1138*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
1139*0b57cec5SDimitry Andric    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1140*0b57cec5SDimitry Andric  }
1141*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __unlock() const {
1142*0b57cec5SDimitry Andric    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
1143*0b57cec5SDimitry Andric  }
1144*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
1145*0b57cec5SDimitry Andric    __lock();
1146*0b57cec5SDimitry Andric    _Tp __old;
1147*0b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(__old, __a_value);
1148*0b57cec5SDimitry Andric    __unlock();
1149*0b57cec5SDimitry Andric    return __old;
1150*0b57cec5SDimitry Andric  }
1151*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
1152*0b57cec5SDimitry Andric    __lock();
1153*0b57cec5SDimitry Andric    _Tp __old = __a_value;
1154*0b57cec5SDimitry Andric    __unlock();
1155*0b57cec5SDimitry Andric    return __old;
1156*0b57cec5SDimitry Andric  }
1157*0b57cec5SDimitry Andric};
1158*0b57cec5SDimitry Andric
1159*0b57cec5SDimitry Andrictemplate <typename _Tp>
1160*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1161*0b57cec5SDimitry Andricvoid __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
1162*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __val);
1163*0b57cec5SDimitry Andric}
1164*0b57cec5SDimitry Andrictemplate <typename _Tp>
1165*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1166*0b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
1167*0b57cec5SDimitry Andric  __a->__a_value = __val;
1168*0b57cec5SDimitry Andric}
1169*0b57cec5SDimitry Andric
1170*0b57cec5SDimitry Andrictemplate <typename _Tp>
1171*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1172*0b57cec5SDimitry Andricvoid __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
1173*0b57cec5SDimitry Andric  __a->__lock();
1174*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __val);
1175*0b57cec5SDimitry Andric  __a->__unlock();
1176*0b57cec5SDimitry Andric}
1177*0b57cec5SDimitry Andrictemplate <typename _Tp>
1178*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1179*0b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
1180*0b57cec5SDimitry Andric  __a->__lock();
1181*0b57cec5SDimitry Andric  __a->__a_value = __val;
1182*0b57cec5SDimitry Andric  __a->__unlock();
1183*0b57cec5SDimitry Andric}
1184*0b57cec5SDimitry Andric
1185*0b57cec5SDimitry Andrictemplate <typename _Tp>
1186*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1187*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1188*0b57cec5SDimitry Andric  return __a->__read();
1189*0b57cec5SDimitry Andric}
1190*0b57cec5SDimitry Andrictemplate <typename _Tp>
1191*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1192*0b57cec5SDimitry Andric_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
1193*0b57cec5SDimitry Andric  return __a->__read();
1194*0b57cec5SDimitry Andric}
1195*0b57cec5SDimitry Andric
1196*0b57cec5SDimitry Andrictemplate <typename _Tp>
1197*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1198*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1199*0b57cec5SDimitry Andric  __a->__lock();
1200*0b57cec5SDimitry Andric  _Tp __old;
1201*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
1202*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __value);
1203*0b57cec5SDimitry Andric  __a->__unlock();
1204*0b57cec5SDimitry Andric  return __old;
1205*0b57cec5SDimitry Andric}
1206*0b57cec5SDimitry Andrictemplate <typename _Tp>
1207*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1208*0b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
1209*0b57cec5SDimitry Andric  __a->__lock();
1210*0b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
1211*0b57cec5SDimitry Andric  __a->__a_value = __value;
1212*0b57cec5SDimitry Andric  __a->__unlock();
1213*0b57cec5SDimitry Andric  return __old;
1214*0b57cec5SDimitry Andric}
1215*0b57cec5SDimitry Andric
1216*0b57cec5SDimitry Andrictemplate <typename _Tp>
1217*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1218*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1219*0b57cec5SDimitry Andric                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
1220*0b57cec5SDimitry Andric  __a->__lock();
1221*0b57cec5SDimitry Andric  _Tp temp;
1222*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(temp, __a->__a_value);
1223*0b57cec5SDimitry Andric  bool __ret = temp == *__expected;
1224*0b57cec5SDimitry Andric  if(__ret)
1225*0b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(__a->__a_value, __value);
1226*0b57cec5SDimitry Andric  else
1227*0b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1228*0b57cec5SDimitry Andric  __a->__unlock();
1229*0b57cec5SDimitry Andric  return __ret;
1230*0b57cec5SDimitry Andric}
1231*0b57cec5SDimitry Andrictemplate <typename _Tp>
1232*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1233*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
1234*0b57cec5SDimitry Andric                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
1235*0b57cec5SDimitry Andric  __a->__lock();
1236*0b57cec5SDimitry Andric  bool __ret = __a->__a_value == *__expected;
1237*0b57cec5SDimitry Andric  if(__ret)
1238*0b57cec5SDimitry Andric    __a->__a_value = __value;
1239*0b57cec5SDimitry Andric  else
1240*0b57cec5SDimitry Andric    *__expected = __a->__a_value;
1241*0b57cec5SDimitry Andric  __a->__unlock();
1242*0b57cec5SDimitry Andric  return __ret;
1243*0b57cec5SDimitry Andric}
1244*0b57cec5SDimitry Andric
1245*0b57cec5SDimitry Andrictemplate <typename _Tp>
1246*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1247*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1248*0b57cec5SDimitry Andric                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
1249*0b57cec5SDimitry Andric  __a->__lock();
1250*0b57cec5SDimitry Andric  _Tp temp;
1251*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(temp, __a->__a_value);
1252*0b57cec5SDimitry Andric  bool __ret = temp == *__expected;
1253*0b57cec5SDimitry Andric  if(__ret)
1254*0b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(__a->__a_value, __value);
1255*0b57cec5SDimitry Andric  else
1256*0b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
1257*0b57cec5SDimitry Andric  __a->__unlock();
1258*0b57cec5SDimitry Andric  return __ret;
1259*0b57cec5SDimitry Andric}
1260*0b57cec5SDimitry Andrictemplate <typename _Tp>
1261*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1262*0b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
1263*0b57cec5SDimitry Andric                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
1264*0b57cec5SDimitry Andric  __a->__lock();
1265*0b57cec5SDimitry Andric  bool __ret = __a->__a_value == *__expected;
1266*0b57cec5SDimitry Andric  if(__ret)
1267*0b57cec5SDimitry Andric    __a->__a_value = __value;
1268*0b57cec5SDimitry Andric  else
1269*0b57cec5SDimitry Andric    *__expected = __a->__a_value;
1270*0b57cec5SDimitry Andric  __a->__unlock();
1271*0b57cec5SDimitry Andric  return __ret;
1272*0b57cec5SDimitry Andric}
1273*0b57cec5SDimitry Andric
1274*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
1275*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1276*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1277*0b57cec5SDimitry Andric                           _Td __delta, memory_order) {
1278*0b57cec5SDimitry Andric  __a->__lock();
1279*0b57cec5SDimitry Andric  _Tp __old;
1280*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
1281*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
1282*0b57cec5SDimitry Andric  __a->__unlock();
1283*0b57cec5SDimitry Andric  return __old;
1284*0b57cec5SDimitry Andric}
1285*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
1286*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1287*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
1288*0b57cec5SDimitry Andric                           _Td __delta, memory_order) {
1289*0b57cec5SDimitry Andric  __a->__lock();
1290*0b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
1291*0b57cec5SDimitry Andric  __a->__a_value += __delta;
1292*0b57cec5SDimitry Andric  __a->__unlock();
1293*0b57cec5SDimitry Andric  return __old;
1294*0b57cec5SDimitry Andric}
1295*0b57cec5SDimitry Andric
1296*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
1297*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1298*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
1299*0b57cec5SDimitry Andric                           ptrdiff_t __delta, memory_order) {
1300*0b57cec5SDimitry Andric  __a->__lock();
1301*0b57cec5SDimitry Andric  _Tp* __old;
1302*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
1303*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
1304*0b57cec5SDimitry Andric  __a->__unlock();
1305*0b57cec5SDimitry Andric  return __old;
1306*0b57cec5SDimitry Andric}
1307*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
1308*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1309*0b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
1310*0b57cec5SDimitry Andric                           ptrdiff_t __delta, memory_order) {
1311*0b57cec5SDimitry Andric  __a->__lock();
1312*0b57cec5SDimitry Andric  _Tp* __old = __a->__a_value;
1313*0b57cec5SDimitry Andric  __a->__a_value += __delta;
1314*0b57cec5SDimitry Andric  __a->__unlock();
1315*0b57cec5SDimitry Andric  return __old;
1316*0b57cec5SDimitry Andric}
1317*0b57cec5SDimitry Andric
1318*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
1319*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1320*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1321*0b57cec5SDimitry Andric                           _Td __delta, memory_order) {
1322*0b57cec5SDimitry Andric  __a->__lock();
1323*0b57cec5SDimitry Andric  _Tp __old;
1324*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
1325*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
1326*0b57cec5SDimitry Andric  __a->__unlock();
1327*0b57cec5SDimitry Andric  return __old;
1328*0b57cec5SDimitry Andric}
1329*0b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
1330*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1331*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
1332*0b57cec5SDimitry Andric                           _Td __delta, memory_order) {
1333*0b57cec5SDimitry Andric  __a->__lock();
1334*0b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
1335*0b57cec5SDimitry Andric  __a->__a_value -= __delta;
1336*0b57cec5SDimitry Andric  __a->__unlock();
1337*0b57cec5SDimitry Andric  return __old;
1338*0b57cec5SDimitry Andric}
1339*0b57cec5SDimitry Andric
1340*0b57cec5SDimitry Andrictemplate <typename _Tp>
1341*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1342*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1343*0b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
1344*0b57cec5SDimitry Andric  __a->__lock();
1345*0b57cec5SDimitry Andric  _Tp __old;
1346*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
1347*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
1348*0b57cec5SDimitry Andric  __a->__unlock();
1349*0b57cec5SDimitry Andric  return __old;
1350*0b57cec5SDimitry Andric}
1351*0b57cec5SDimitry Andrictemplate <typename _Tp>
1352*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1353*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
1354*0b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
1355*0b57cec5SDimitry Andric  __a->__lock();
1356*0b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
1357*0b57cec5SDimitry Andric  __a->__a_value &= __pattern;
1358*0b57cec5SDimitry Andric  __a->__unlock();
1359*0b57cec5SDimitry Andric  return __old;
1360*0b57cec5SDimitry Andric}
1361*0b57cec5SDimitry Andric
1362*0b57cec5SDimitry Andrictemplate <typename _Tp>
1363*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1364*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1365*0b57cec5SDimitry Andric                          _Tp __pattern, memory_order) {
1366*0b57cec5SDimitry Andric  __a->__lock();
1367*0b57cec5SDimitry Andric  _Tp __old;
1368*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
1369*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
1370*0b57cec5SDimitry Andric  __a->__unlock();
1371*0b57cec5SDimitry Andric  return __old;
1372*0b57cec5SDimitry Andric}
1373*0b57cec5SDimitry Andrictemplate <typename _Tp>
1374*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1375*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
1376*0b57cec5SDimitry Andric                          _Tp __pattern, memory_order) {
1377*0b57cec5SDimitry Andric  __a->__lock();
1378*0b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
1379*0b57cec5SDimitry Andric  __a->__a_value |= __pattern;
1380*0b57cec5SDimitry Andric  __a->__unlock();
1381*0b57cec5SDimitry Andric  return __old;
1382*0b57cec5SDimitry Andric}
1383*0b57cec5SDimitry Andric
1384*0b57cec5SDimitry Andrictemplate <typename _Tp>
1385*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1386*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
1387*0b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
1388*0b57cec5SDimitry Andric  __a->__lock();
1389*0b57cec5SDimitry Andric  _Tp __old;
1390*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
1391*0b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
1392*0b57cec5SDimitry Andric  __a->__unlock();
1393*0b57cec5SDimitry Andric  return __old;
1394*0b57cec5SDimitry Andric}
1395*0b57cec5SDimitry Andrictemplate <typename _Tp>
1396*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1397*0b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
1398*0b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
1399*0b57cec5SDimitry Andric  __a->__lock();
1400*0b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
1401*0b57cec5SDimitry Andric  __a->__a_value ^= __pattern;
1402*0b57cec5SDimitry Andric  __a->__unlock();
1403*0b57cec5SDimitry Andric  return __old;
1404*0b57cec5SDimitry Andric}
1405*0b57cec5SDimitry Andric
1406*0b57cec5SDimitry Andric#ifdef __cpp_lib_atomic_is_always_lock_free
1407*0b57cec5SDimitry Andric
1408*0b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free {
1409*0b57cec5SDimitry Andric    enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
1410*0b57cec5SDimitry Andric
1411*0b57cec5SDimitry Andric#else
1412*0b57cec5SDimitry Andric
1413*0b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
1414*0b57cec5SDimitry Andric// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
1415*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
1416*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1417*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1418*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
1419*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
1420*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
1421*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
1422*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1423*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
1424*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1425*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
1426*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1427*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
1428*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1429*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
1430*0b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1431*0b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
1432*0b57cec5SDimitry Andric
1433*0b57cec5SDimitry Andric#endif //__cpp_lib_atomic_is_always_lock_free
1434*0b57cec5SDimitry Andric
1435*0b57cec5SDimitry Andrictemplate <typename _Tp,
1436*0b57cec5SDimitry Andric          typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
1437*0b57cec5SDimitry Andric                                                __cxx_atomic_base_impl<_Tp>,
1438*0b57cec5SDimitry Andric                                                __cxx_atomic_lock_impl<_Tp> >::type>
1439*0b57cec5SDimitry Andric#else
1440*0b57cec5SDimitry Andrictemplate <typename _Tp,
1441*0b57cec5SDimitry Andric          typename _Base = __cxx_atomic_base_impl<_Tp> >
1442*0b57cec5SDimitry Andric#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
1443*0b57cec5SDimitry Andricstruct __cxx_atomic_impl : public _Base {
1444*0b57cec5SDimitry Andric
1445*0b57cec5SDimitry Andric#if _GNUC_VER >= 501
1446*0b57cec5SDimitry Andric    static_assert(is_trivially_copyable<_Tp>::value,
1447*0b57cec5SDimitry Andric      "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
1448*0b57cec5SDimitry Andric#endif
1449*0b57cec5SDimitry Andric
1450*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
1451*0b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
1452*0b57cec5SDimitry Andric    : _Base(value) {}
1453*0b57cec5SDimitry Andric};
1454*0b57cec5SDimitry Andric
1455*0b57cec5SDimitry Andric// general atomic<T>
1456*0b57cec5SDimitry Andric
1457*0b57cec5SDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
1458*0b57cec5SDimitry Andricstruct __atomic_base  // false
1459*0b57cec5SDimitry Andric{
1460*0b57cec5SDimitry Andric    mutable __cxx_atomic_impl<_Tp> __a_;
1461*0b57cec5SDimitry Andric
1462*0b57cec5SDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free)
1463*0b57cec5SDimitry Andric  static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
1464*0b57cec5SDimitry Andric#endif
1465*0b57cec5SDimitry Andric
1466*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1467*0b57cec5SDimitry Andric    bool is_lock_free() const volatile _NOEXCEPT
1468*0b57cec5SDimitry Andric        {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
1469*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1470*0b57cec5SDimitry Andric    bool is_lock_free() const _NOEXCEPT
1471*0b57cec5SDimitry Andric        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
1472*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1473*0b57cec5SDimitry Andric    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1474*0b57cec5SDimitry Andric      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1475*0b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, __d, __m);}
1476*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1477*0b57cec5SDimitry Andric    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1478*0b57cec5SDimitry Andric      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1479*0b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, __d, __m);}
1480*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1481*0b57cec5SDimitry Andric    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
1482*0b57cec5SDimitry Andric      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1483*0b57cec5SDimitry Andric        {return __cxx_atomic_load(&__a_, __m);}
1484*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1485*0b57cec5SDimitry Andric    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
1486*0b57cec5SDimitry Andric      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1487*0b57cec5SDimitry Andric        {return __cxx_atomic_load(&__a_, __m);}
1488*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1489*0b57cec5SDimitry Andric    operator _Tp() const volatile _NOEXCEPT {return load();}
1490*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1491*0b57cec5SDimitry Andric    operator _Tp() const _NOEXCEPT          {return load();}
1492*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1493*0b57cec5SDimitry Andric    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1494*0b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, __d, __m);}
1495*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1496*0b57cec5SDimitry Andric    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1497*0b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, __d, __m);}
1498*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1499*0b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1500*0b57cec5SDimitry Andric                               memory_order __s, memory_order __f) volatile _NOEXCEPT
1501*0b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1502*0b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
1503*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1504*0b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1505*0b57cec5SDimitry Andric                               memory_order __s, memory_order __f) _NOEXCEPT
1506*0b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1507*0b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
1508*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1509*0b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1510*0b57cec5SDimitry Andric                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
1511*0b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1512*0b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
1513*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1514*0b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1515*0b57cec5SDimitry Andric                                 memory_order __s, memory_order __f) _NOEXCEPT
1516*0b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1517*0b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
1518*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1519*0b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1520*0b57cec5SDimitry Andric                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1521*0b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
1522*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1523*0b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
1524*0b57cec5SDimitry Andric                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
1525*0b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
1526*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1527*0b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1528*0b57cec5SDimitry Andric                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1529*0b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
1530*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1531*0b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
1532*0b57cec5SDimitry Andric                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
1533*0b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
1534*0b57cec5SDimitry Andric
1535*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1536*0b57cec5SDimitry Andric    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
1537*0b57cec5SDimitry Andric
1538*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
1539*0b57cec5SDimitry Andric    __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
1540*0b57cec5SDimitry Andric
1541*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
1542*0b57cec5SDimitry Andric    __atomic_base(const __atomic_base&) = delete;
1543*0b57cec5SDimitry Andric    __atomic_base& operator=(const __atomic_base&) = delete;
1544*0b57cec5SDimitry Andric    __atomic_base& operator=(const __atomic_base&) volatile = delete;
1545*0b57cec5SDimitry Andric#else
1546*0b57cec5SDimitry Andricprivate:
1547*0b57cec5SDimitry Andric    __atomic_base(const __atomic_base&);
1548*0b57cec5SDimitry Andric    __atomic_base& operator=(const __atomic_base&);
1549*0b57cec5SDimitry Andric    __atomic_base& operator=(const __atomic_base&) volatile;
1550*0b57cec5SDimitry Andric#endif
1551*0b57cec5SDimitry Andric};
1552*0b57cec5SDimitry Andric
1553*0b57cec5SDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free)
1554*0b57cec5SDimitry Andrictemplate <class _Tp, bool __b>
1555*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
1556*0b57cec5SDimitry Andric#endif
1557*0b57cec5SDimitry Andric
1558*0b57cec5SDimitry Andric// atomic<Integral>
1559*0b57cec5SDimitry Andric
1560*0b57cec5SDimitry Andrictemplate <class _Tp>
1561*0b57cec5SDimitry Andricstruct __atomic_base<_Tp, true>
1562*0b57cec5SDimitry Andric    : public __atomic_base<_Tp, false>
1563*0b57cec5SDimitry Andric{
1564*0b57cec5SDimitry Andric    typedef __atomic_base<_Tp, false> __base;
1565*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1566*0b57cec5SDimitry Andric    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
1567*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1568*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
1569*0b57cec5SDimitry Andric
1570*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1571*0b57cec5SDimitry Andric    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1572*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1573*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1574*0b57cec5SDimitry Andric    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1575*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1576*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1577*0b57cec5SDimitry Andric    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1578*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1579*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1580*0b57cec5SDimitry Andric    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1581*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1582*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1583*0b57cec5SDimitry Andric    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1584*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
1585*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1586*0b57cec5SDimitry Andric    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1587*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
1588*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1589*0b57cec5SDimitry Andric    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1590*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
1591*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1592*0b57cec5SDimitry Andric    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1593*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
1594*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1595*0b57cec5SDimitry Andric    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1596*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
1597*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1598*0b57cec5SDimitry Andric    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1599*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
1600*0b57cec5SDimitry Andric
1601*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1602*0b57cec5SDimitry Andric    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
1603*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1604*0b57cec5SDimitry Andric    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
1605*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1606*0b57cec5SDimitry Andric    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
1607*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1608*0b57cec5SDimitry Andric    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
1609*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1610*0b57cec5SDimitry Andric    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
1611*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1612*0b57cec5SDimitry Andric    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
1613*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1614*0b57cec5SDimitry Andric    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
1615*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1616*0b57cec5SDimitry Andric    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
1617*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1618*0b57cec5SDimitry Andric    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1619*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1620*0b57cec5SDimitry Andric    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
1621*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1622*0b57cec5SDimitry Andric    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1623*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1624*0b57cec5SDimitry Andric    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1625*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1626*0b57cec5SDimitry Andric    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
1627*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1628*0b57cec5SDimitry Andric    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
1629*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1630*0b57cec5SDimitry Andric    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
1631*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1632*0b57cec5SDimitry Andric    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
1633*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1634*0b57cec5SDimitry Andric    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
1635*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1636*0b57cec5SDimitry Andric    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
1637*0b57cec5SDimitry Andric};
1638*0b57cec5SDimitry Andric
1639*0b57cec5SDimitry Andric// atomic<T>
1640*0b57cec5SDimitry Andric
1641*0b57cec5SDimitry Andrictemplate <class _Tp>
1642*0b57cec5SDimitry Andricstruct atomic
1643*0b57cec5SDimitry Andric    : public __atomic_base<_Tp>
1644*0b57cec5SDimitry Andric{
1645*0b57cec5SDimitry Andric    typedef __atomic_base<_Tp> __base;
1646*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1647*0b57cec5SDimitry Andric    atomic() _NOEXCEPT _LIBCPP_DEFAULT
1648*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1649*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
1650*0b57cec5SDimitry Andric
1651*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1652*0b57cec5SDimitry Andric    _Tp operator=(_Tp __d) volatile _NOEXCEPT
1653*0b57cec5SDimitry Andric        {__base::store(__d); return __d;}
1654*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1655*0b57cec5SDimitry Andric    _Tp operator=(_Tp __d) _NOEXCEPT
1656*0b57cec5SDimitry Andric        {__base::store(__d); return __d;}
1657*0b57cec5SDimitry Andric};
1658*0b57cec5SDimitry Andric
1659*0b57cec5SDimitry Andric// atomic<T*>
1660*0b57cec5SDimitry Andric
1661*0b57cec5SDimitry Andrictemplate <class _Tp>
1662*0b57cec5SDimitry Andricstruct atomic<_Tp*>
1663*0b57cec5SDimitry Andric    : public __atomic_base<_Tp*>
1664*0b57cec5SDimitry Andric{
1665*0b57cec5SDimitry Andric    typedef __atomic_base<_Tp*> __base;
1666*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1667*0b57cec5SDimitry Andric    atomic() _NOEXCEPT _LIBCPP_DEFAULT
1668*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1669*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
1670*0b57cec5SDimitry Andric
1671*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1672*0b57cec5SDimitry Andric    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
1673*0b57cec5SDimitry Andric        {__base::store(__d); return __d;}
1674*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1675*0b57cec5SDimitry Andric    _Tp* operator=(_Tp* __d) _NOEXCEPT
1676*0b57cec5SDimitry Andric        {__base::store(__d); return __d;}
1677*0b57cec5SDimitry Andric
1678*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1679*0b57cec5SDimitry Andric    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
1680*0b57cec5SDimitry Andric                                                                        volatile _NOEXCEPT
1681*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1682*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1683*0b57cec5SDimitry Andric    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1684*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
1685*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1686*0b57cec5SDimitry Andric    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
1687*0b57cec5SDimitry Andric                                                                        volatile _NOEXCEPT
1688*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1689*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1690*0b57cec5SDimitry Andric    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1691*0b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
1692*0b57cec5SDimitry Andric
1693*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1694*0b57cec5SDimitry Andric    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
1695*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1696*0b57cec5SDimitry Andric    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
1697*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1698*0b57cec5SDimitry Andric    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
1699*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1700*0b57cec5SDimitry Andric    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
1701*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1702*0b57cec5SDimitry Andric    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
1703*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1704*0b57cec5SDimitry Andric    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
1705*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1706*0b57cec5SDimitry Andric    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
1707*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1708*0b57cec5SDimitry Andric    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
1709*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1710*0b57cec5SDimitry Andric    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
1711*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1712*0b57cec5SDimitry Andric    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
1713*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1714*0b57cec5SDimitry Andric    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
1715*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1716*0b57cec5SDimitry Andric    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
1717*0b57cec5SDimitry Andric};
1718*0b57cec5SDimitry Andric
1719*0b57cec5SDimitry Andric// atomic_is_lock_free
1720*0b57cec5SDimitry Andric
1721*0b57cec5SDimitry Andrictemplate <class _Tp>
1722*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1723*0b57cec5SDimitry Andricbool
1724*0b57cec5SDimitry Andricatomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
1725*0b57cec5SDimitry Andric{
1726*0b57cec5SDimitry Andric    return __o->is_lock_free();
1727*0b57cec5SDimitry Andric}
1728*0b57cec5SDimitry Andric
1729*0b57cec5SDimitry Andrictemplate <class _Tp>
1730*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1731*0b57cec5SDimitry Andricbool
1732*0b57cec5SDimitry Andricatomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
1733*0b57cec5SDimitry Andric{
1734*0b57cec5SDimitry Andric    return __o->is_lock_free();
1735*0b57cec5SDimitry Andric}
1736*0b57cec5SDimitry Andric
1737*0b57cec5SDimitry Andric// atomic_init
1738*0b57cec5SDimitry Andric
1739*0b57cec5SDimitry Andrictemplate <class _Tp>
1740*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1741*0b57cec5SDimitry Andricvoid
1742*0b57cec5SDimitry Andricatomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1743*0b57cec5SDimitry Andric{
1744*0b57cec5SDimitry Andric    __cxx_atomic_init(&__o->__a_, __d);
1745*0b57cec5SDimitry Andric}
1746*0b57cec5SDimitry Andric
1747*0b57cec5SDimitry Andrictemplate <class _Tp>
1748*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1749*0b57cec5SDimitry Andricvoid
1750*0b57cec5SDimitry Andricatomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1751*0b57cec5SDimitry Andric{
1752*0b57cec5SDimitry Andric    __cxx_atomic_init(&__o->__a_, __d);
1753*0b57cec5SDimitry Andric}
1754*0b57cec5SDimitry Andric
1755*0b57cec5SDimitry Andric// atomic_store
1756*0b57cec5SDimitry Andric
1757*0b57cec5SDimitry Andrictemplate <class _Tp>
1758*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1759*0b57cec5SDimitry Andricvoid
1760*0b57cec5SDimitry Andricatomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1761*0b57cec5SDimitry Andric{
1762*0b57cec5SDimitry Andric    __o->store(__d);
1763*0b57cec5SDimitry Andric}
1764*0b57cec5SDimitry Andric
1765*0b57cec5SDimitry Andrictemplate <class _Tp>
1766*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1767*0b57cec5SDimitry Andricvoid
1768*0b57cec5SDimitry Andricatomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1769*0b57cec5SDimitry Andric{
1770*0b57cec5SDimitry Andric    __o->store(__d);
1771*0b57cec5SDimitry Andric}
1772*0b57cec5SDimitry Andric
1773*0b57cec5SDimitry Andric// atomic_store_explicit
1774*0b57cec5SDimitry Andric
1775*0b57cec5SDimitry Andrictemplate <class _Tp>
1776*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1777*0b57cec5SDimitry Andricvoid
1778*0b57cec5SDimitry Andricatomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1779*0b57cec5SDimitry Andric  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1780*0b57cec5SDimitry Andric{
1781*0b57cec5SDimitry Andric    __o->store(__d, __m);
1782*0b57cec5SDimitry Andric}
1783*0b57cec5SDimitry Andric
1784*0b57cec5SDimitry Andrictemplate <class _Tp>
1785*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1786*0b57cec5SDimitry Andricvoid
1787*0b57cec5SDimitry Andricatomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1788*0b57cec5SDimitry Andric  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
1789*0b57cec5SDimitry Andric{
1790*0b57cec5SDimitry Andric    __o->store(__d, __m);
1791*0b57cec5SDimitry Andric}
1792*0b57cec5SDimitry Andric
1793*0b57cec5SDimitry Andric// atomic_load
1794*0b57cec5SDimitry Andric
1795*0b57cec5SDimitry Andrictemplate <class _Tp>
1796*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1797*0b57cec5SDimitry Andric_Tp
1798*0b57cec5SDimitry Andricatomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
1799*0b57cec5SDimitry Andric{
1800*0b57cec5SDimitry Andric    return __o->load();
1801*0b57cec5SDimitry Andric}
1802*0b57cec5SDimitry Andric
1803*0b57cec5SDimitry Andrictemplate <class _Tp>
1804*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1805*0b57cec5SDimitry Andric_Tp
1806*0b57cec5SDimitry Andricatomic_load(const atomic<_Tp>* __o) _NOEXCEPT
1807*0b57cec5SDimitry Andric{
1808*0b57cec5SDimitry Andric    return __o->load();
1809*0b57cec5SDimitry Andric}
1810*0b57cec5SDimitry Andric
1811*0b57cec5SDimitry Andric// atomic_load_explicit
1812*0b57cec5SDimitry Andric
1813*0b57cec5SDimitry Andrictemplate <class _Tp>
1814*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1815*0b57cec5SDimitry Andric_Tp
1816*0b57cec5SDimitry Andricatomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1817*0b57cec5SDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1818*0b57cec5SDimitry Andric{
1819*0b57cec5SDimitry Andric    return __o->load(__m);
1820*0b57cec5SDimitry Andric}
1821*0b57cec5SDimitry Andric
1822*0b57cec5SDimitry Andrictemplate <class _Tp>
1823*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1824*0b57cec5SDimitry Andric_Tp
1825*0b57cec5SDimitry Andricatomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1826*0b57cec5SDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
1827*0b57cec5SDimitry Andric{
1828*0b57cec5SDimitry Andric    return __o->load(__m);
1829*0b57cec5SDimitry Andric}
1830*0b57cec5SDimitry Andric
1831*0b57cec5SDimitry Andric// atomic_exchange
1832*0b57cec5SDimitry Andric
1833*0b57cec5SDimitry Andrictemplate <class _Tp>
1834*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1835*0b57cec5SDimitry Andric_Tp
1836*0b57cec5SDimitry Andricatomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1837*0b57cec5SDimitry Andric{
1838*0b57cec5SDimitry Andric    return __o->exchange(__d);
1839*0b57cec5SDimitry Andric}
1840*0b57cec5SDimitry Andric
1841*0b57cec5SDimitry Andrictemplate <class _Tp>
1842*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1843*0b57cec5SDimitry Andric_Tp
1844*0b57cec5SDimitry Andricatomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
1845*0b57cec5SDimitry Andric{
1846*0b57cec5SDimitry Andric    return __o->exchange(__d);
1847*0b57cec5SDimitry Andric}
1848*0b57cec5SDimitry Andric
1849*0b57cec5SDimitry Andric// atomic_exchange_explicit
1850*0b57cec5SDimitry Andric
1851*0b57cec5SDimitry Andrictemplate <class _Tp>
1852*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1853*0b57cec5SDimitry Andric_Tp
1854*0b57cec5SDimitry Andricatomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1855*0b57cec5SDimitry Andric{
1856*0b57cec5SDimitry Andric    return __o->exchange(__d, __m);
1857*0b57cec5SDimitry Andric}
1858*0b57cec5SDimitry Andric
1859*0b57cec5SDimitry Andrictemplate <class _Tp>
1860*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1861*0b57cec5SDimitry Andric_Tp
1862*0b57cec5SDimitry Andricatomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1863*0b57cec5SDimitry Andric{
1864*0b57cec5SDimitry Andric    return __o->exchange(__d, __m);
1865*0b57cec5SDimitry Andric}
1866*0b57cec5SDimitry Andric
1867*0b57cec5SDimitry Andric// atomic_compare_exchange_weak
1868*0b57cec5SDimitry Andric
1869*0b57cec5SDimitry Andrictemplate <class _Tp>
1870*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1871*0b57cec5SDimitry Andricbool
1872*0b57cec5SDimitry Andricatomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1873*0b57cec5SDimitry Andric{
1874*0b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d);
1875*0b57cec5SDimitry Andric}
1876*0b57cec5SDimitry Andric
1877*0b57cec5SDimitry Andrictemplate <class _Tp>
1878*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1879*0b57cec5SDimitry Andricbool
1880*0b57cec5SDimitry Andricatomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1881*0b57cec5SDimitry Andric{
1882*0b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d);
1883*0b57cec5SDimitry Andric}
1884*0b57cec5SDimitry Andric
1885*0b57cec5SDimitry Andric// atomic_compare_exchange_strong
1886*0b57cec5SDimitry Andric
1887*0b57cec5SDimitry Andrictemplate <class _Tp>
1888*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1889*0b57cec5SDimitry Andricbool
1890*0b57cec5SDimitry Andricatomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1891*0b57cec5SDimitry Andric{
1892*0b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d);
1893*0b57cec5SDimitry Andric}
1894*0b57cec5SDimitry Andric
1895*0b57cec5SDimitry Andrictemplate <class _Tp>
1896*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1897*0b57cec5SDimitry Andricbool
1898*0b57cec5SDimitry Andricatomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
1899*0b57cec5SDimitry Andric{
1900*0b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d);
1901*0b57cec5SDimitry Andric}
1902*0b57cec5SDimitry Andric
1903*0b57cec5SDimitry Andric// atomic_compare_exchange_weak_explicit
1904*0b57cec5SDimitry Andric
1905*0b57cec5SDimitry Andrictemplate <class _Tp>
1906*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1907*0b57cec5SDimitry Andricbool
1908*0b57cec5SDimitry Andricatomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
1909*0b57cec5SDimitry Andric                                      _Tp __d,
1910*0b57cec5SDimitry Andric                                      memory_order __s, memory_order __f) _NOEXCEPT
1911*0b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1912*0b57cec5SDimitry Andric{
1913*0b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d, __s, __f);
1914*0b57cec5SDimitry Andric}
1915*0b57cec5SDimitry Andric
1916*0b57cec5SDimitry Andrictemplate <class _Tp>
1917*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1918*0b57cec5SDimitry Andricbool
1919*0b57cec5SDimitry Andricatomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
1920*0b57cec5SDimitry Andric                                      memory_order __s, memory_order __f) _NOEXCEPT
1921*0b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1922*0b57cec5SDimitry Andric{
1923*0b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d, __s, __f);
1924*0b57cec5SDimitry Andric}
1925*0b57cec5SDimitry Andric
1926*0b57cec5SDimitry Andric// atomic_compare_exchange_strong_explicit
1927*0b57cec5SDimitry Andric
1928*0b57cec5SDimitry Andrictemplate <class _Tp>
1929*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1930*0b57cec5SDimitry Andricbool
1931*0b57cec5SDimitry Andricatomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1932*0b57cec5SDimitry Andric                                        _Tp* __e, _Tp __d,
1933*0b57cec5SDimitry Andric                                        memory_order __s, memory_order __f) _NOEXCEPT
1934*0b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1935*0b57cec5SDimitry Andric{
1936*0b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1937*0b57cec5SDimitry Andric}
1938*0b57cec5SDimitry Andric
1939*0b57cec5SDimitry Andrictemplate <class _Tp>
1940*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1941*0b57cec5SDimitry Andricbool
1942*0b57cec5SDimitry Andricatomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1943*0b57cec5SDimitry Andric                                        _Tp __d,
1944*0b57cec5SDimitry Andric                                        memory_order __s, memory_order __f) _NOEXCEPT
1945*0b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
1946*0b57cec5SDimitry Andric{
1947*0b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1948*0b57cec5SDimitry Andric}
1949*0b57cec5SDimitry Andric
1950*0b57cec5SDimitry Andric// atomic_fetch_add
1951*0b57cec5SDimitry Andric
1952*0b57cec5SDimitry Andrictemplate <class _Tp>
1953*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1954*0b57cec5SDimitry Andrictypename enable_if
1955*0b57cec5SDimitry Andric<
1956*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1957*0b57cec5SDimitry Andric    _Tp
1958*0b57cec5SDimitry Andric>::type
1959*0b57cec5SDimitry Andricatomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1960*0b57cec5SDimitry Andric{
1961*0b57cec5SDimitry Andric    return __o->fetch_add(__op);
1962*0b57cec5SDimitry Andric}
1963*0b57cec5SDimitry Andric
1964*0b57cec5SDimitry Andrictemplate <class _Tp>
1965*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1966*0b57cec5SDimitry Andrictypename enable_if
1967*0b57cec5SDimitry Andric<
1968*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1969*0b57cec5SDimitry Andric    _Tp
1970*0b57cec5SDimitry Andric>::type
1971*0b57cec5SDimitry Andricatomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1972*0b57cec5SDimitry Andric{
1973*0b57cec5SDimitry Andric    return __o->fetch_add(__op);
1974*0b57cec5SDimitry Andric}
1975*0b57cec5SDimitry Andric
1976*0b57cec5SDimitry Andrictemplate <class _Tp>
1977*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1978*0b57cec5SDimitry Andric_Tp*
1979*0b57cec5SDimitry Andricatomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1980*0b57cec5SDimitry Andric{
1981*0b57cec5SDimitry Andric    return __o->fetch_add(__op);
1982*0b57cec5SDimitry Andric}
1983*0b57cec5SDimitry Andric
1984*0b57cec5SDimitry Andrictemplate <class _Tp>
1985*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1986*0b57cec5SDimitry Andric_Tp*
1987*0b57cec5SDimitry Andricatomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1988*0b57cec5SDimitry Andric{
1989*0b57cec5SDimitry Andric    return __o->fetch_add(__op);
1990*0b57cec5SDimitry Andric}
1991*0b57cec5SDimitry Andric
1992*0b57cec5SDimitry Andric// atomic_fetch_add_explicit
1993*0b57cec5SDimitry Andric
1994*0b57cec5SDimitry Andrictemplate <class _Tp>
1995*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
1996*0b57cec5SDimitry Andrictypename enable_if
1997*0b57cec5SDimitry Andric<
1998*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1999*0b57cec5SDimitry Andric    _Tp
2000*0b57cec5SDimitry Andric>::type
2001*0b57cec5SDimitry Andricatomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2002*0b57cec5SDimitry Andric{
2003*0b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
2004*0b57cec5SDimitry Andric}
2005*0b57cec5SDimitry Andric
2006*0b57cec5SDimitry Andrictemplate <class _Tp>
2007*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2008*0b57cec5SDimitry Andrictypename enable_if
2009*0b57cec5SDimitry Andric<
2010*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2011*0b57cec5SDimitry Andric    _Tp
2012*0b57cec5SDimitry Andric>::type
2013*0b57cec5SDimitry Andricatomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2014*0b57cec5SDimitry Andric{
2015*0b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
2016*0b57cec5SDimitry Andric}
2017*0b57cec5SDimitry Andric
2018*0b57cec5SDimitry Andrictemplate <class _Tp>
2019*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2020*0b57cec5SDimitry Andric_Tp*
2021*0b57cec5SDimitry Andricatomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
2022*0b57cec5SDimitry Andric                          memory_order __m) _NOEXCEPT
2023*0b57cec5SDimitry Andric{
2024*0b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
2025*0b57cec5SDimitry Andric}
2026*0b57cec5SDimitry Andric
2027*0b57cec5SDimitry Andrictemplate <class _Tp>
2028*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2029*0b57cec5SDimitry Andric_Tp*
2030*0b57cec5SDimitry Andricatomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
2031*0b57cec5SDimitry Andric{
2032*0b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
2033*0b57cec5SDimitry Andric}
2034*0b57cec5SDimitry Andric
2035*0b57cec5SDimitry Andric// atomic_fetch_sub
2036*0b57cec5SDimitry Andric
2037*0b57cec5SDimitry Andrictemplate <class _Tp>
2038*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2039*0b57cec5SDimitry Andrictypename enable_if
2040*0b57cec5SDimitry Andric<
2041*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2042*0b57cec5SDimitry Andric    _Tp
2043*0b57cec5SDimitry Andric>::type
2044*0b57cec5SDimitry Andricatomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
2045*0b57cec5SDimitry Andric{
2046*0b57cec5SDimitry Andric    return __o->fetch_sub(__op);
2047*0b57cec5SDimitry Andric}
2048*0b57cec5SDimitry Andric
2049*0b57cec5SDimitry Andrictemplate <class _Tp>
2050*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2051*0b57cec5SDimitry Andrictypename enable_if
2052*0b57cec5SDimitry Andric<
2053*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2054*0b57cec5SDimitry Andric    _Tp
2055*0b57cec5SDimitry Andric>::type
2056*0b57cec5SDimitry Andricatomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
2057*0b57cec5SDimitry Andric{
2058*0b57cec5SDimitry Andric    return __o->fetch_sub(__op);
2059*0b57cec5SDimitry Andric}
2060*0b57cec5SDimitry Andric
2061*0b57cec5SDimitry Andrictemplate <class _Tp>
2062*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2063*0b57cec5SDimitry Andric_Tp*
2064*0b57cec5SDimitry Andricatomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
2065*0b57cec5SDimitry Andric{
2066*0b57cec5SDimitry Andric    return __o->fetch_sub(__op);
2067*0b57cec5SDimitry Andric}
2068*0b57cec5SDimitry Andric
2069*0b57cec5SDimitry Andrictemplate <class _Tp>
2070*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2071*0b57cec5SDimitry Andric_Tp*
2072*0b57cec5SDimitry Andricatomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
2073*0b57cec5SDimitry Andric{
2074*0b57cec5SDimitry Andric    return __o->fetch_sub(__op);
2075*0b57cec5SDimitry Andric}
2076*0b57cec5SDimitry Andric
2077*0b57cec5SDimitry Andric// atomic_fetch_sub_explicit
2078*0b57cec5SDimitry Andric
2079*0b57cec5SDimitry Andrictemplate <class _Tp>
2080*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2081*0b57cec5SDimitry Andrictypename enable_if
2082*0b57cec5SDimitry Andric<
2083*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2084*0b57cec5SDimitry Andric    _Tp
2085*0b57cec5SDimitry Andric>::type
2086*0b57cec5SDimitry Andricatomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2087*0b57cec5SDimitry Andric{
2088*0b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
2089*0b57cec5SDimitry Andric}
2090*0b57cec5SDimitry Andric
2091*0b57cec5SDimitry Andrictemplate <class _Tp>
2092*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2093*0b57cec5SDimitry Andrictypename enable_if
2094*0b57cec5SDimitry Andric<
2095*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2096*0b57cec5SDimitry Andric    _Tp
2097*0b57cec5SDimitry Andric>::type
2098*0b57cec5SDimitry Andricatomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2099*0b57cec5SDimitry Andric{
2100*0b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
2101*0b57cec5SDimitry Andric}
2102*0b57cec5SDimitry Andric
2103*0b57cec5SDimitry Andrictemplate <class _Tp>
2104*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2105*0b57cec5SDimitry Andric_Tp*
2106*0b57cec5SDimitry Andricatomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
2107*0b57cec5SDimitry Andric                          memory_order __m) _NOEXCEPT
2108*0b57cec5SDimitry Andric{
2109*0b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
2110*0b57cec5SDimitry Andric}
2111*0b57cec5SDimitry Andric
2112*0b57cec5SDimitry Andrictemplate <class _Tp>
2113*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2114*0b57cec5SDimitry Andric_Tp*
2115*0b57cec5SDimitry Andricatomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
2116*0b57cec5SDimitry Andric{
2117*0b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
2118*0b57cec5SDimitry Andric}
2119*0b57cec5SDimitry Andric
2120*0b57cec5SDimitry Andric// atomic_fetch_and
2121*0b57cec5SDimitry Andric
2122*0b57cec5SDimitry Andrictemplate <class _Tp>
2123*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2124*0b57cec5SDimitry Andrictypename enable_if
2125*0b57cec5SDimitry Andric<
2126*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2127*0b57cec5SDimitry Andric    _Tp
2128*0b57cec5SDimitry Andric>::type
2129*0b57cec5SDimitry Andricatomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
2130*0b57cec5SDimitry Andric{
2131*0b57cec5SDimitry Andric    return __o->fetch_and(__op);
2132*0b57cec5SDimitry Andric}
2133*0b57cec5SDimitry Andric
2134*0b57cec5SDimitry Andrictemplate <class _Tp>
2135*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2136*0b57cec5SDimitry Andrictypename enable_if
2137*0b57cec5SDimitry Andric<
2138*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2139*0b57cec5SDimitry Andric    _Tp
2140*0b57cec5SDimitry Andric>::type
2141*0b57cec5SDimitry Andricatomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
2142*0b57cec5SDimitry Andric{
2143*0b57cec5SDimitry Andric    return __o->fetch_and(__op);
2144*0b57cec5SDimitry Andric}
2145*0b57cec5SDimitry Andric
2146*0b57cec5SDimitry Andric// atomic_fetch_and_explicit
2147*0b57cec5SDimitry Andric
2148*0b57cec5SDimitry Andrictemplate <class _Tp>
2149*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2150*0b57cec5SDimitry Andrictypename enable_if
2151*0b57cec5SDimitry Andric<
2152*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2153*0b57cec5SDimitry Andric    _Tp
2154*0b57cec5SDimitry Andric>::type
2155*0b57cec5SDimitry Andricatomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2156*0b57cec5SDimitry Andric{
2157*0b57cec5SDimitry Andric    return __o->fetch_and(__op, __m);
2158*0b57cec5SDimitry Andric}
2159*0b57cec5SDimitry Andric
2160*0b57cec5SDimitry Andrictemplate <class _Tp>
2161*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2162*0b57cec5SDimitry Andrictypename enable_if
2163*0b57cec5SDimitry Andric<
2164*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2165*0b57cec5SDimitry Andric    _Tp
2166*0b57cec5SDimitry Andric>::type
2167*0b57cec5SDimitry Andricatomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2168*0b57cec5SDimitry Andric{
2169*0b57cec5SDimitry Andric    return __o->fetch_and(__op, __m);
2170*0b57cec5SDimitry Andric}
2171*0b57cec5SDimitry Andric
2172*0b57cec5SDimitry Andric// atomic_fetch_or
2173*0b57cec5SDimitry Andric
2174*0b57cec5SDimitry Andrictemplate <class _Tp>
2175*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2176*0b57cec5SDimitry Andrictypename enable_if
2177*0b57cec5SDimitry Andric<
2178*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2179*0b57cec5SDimitry Andric    _Tp
2180*0b57cec5SDimitry Andric>::type
2181*0b57cec5SDimitry Andricatomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
2182*0b57cec5SDimitry Andric{
2183*0b57cec5SDimitry Andric    return __o->fetch_or(__op);
2184*0b57cec5SDimitry Andric}
2185*0b57cec5SDimitry Andric
2186*0b57cec5SDimitry Andrictemplate <class _Tp>
2187*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2188*0b57cec5SDimitry Andrictypename enable_if
2189*0b57cec5SDimitry Andric<
2190*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2191*0b57cec5SDimitry Andric    _Tp
2192*0b57cec5SDimitry Andric>::type
2193*0b57cec5SDimitry Andricatomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
2194*0b57cec5SDimitry Andric{
2195*0b57cec5SDimitry Andric    return __o->fetch_or(__op);
2196*0b57cec5SDimitry Andric}
2197*0b57cec5SDimitry Andric
2198*0b57cec5SDimitry Andric// atomic_fetch_or_explicit
2199*0b57cec5SDimitry Andric
2200*0b57cec5SDimitry Andrictemplate <class _Tp>
2201*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2202*0b57cec5SDimitry Andrictypename enable_if
2203*0b57cec5SDimitry Andric<
2204*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2205*0b57cec5SDimitry Andric    _Tp
2206*0b57cec5SDimitry Andric>::type
2207*0b57cec5SDimitry Andricatomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2208*0b57cec5SDimitry Andric{
2209*0b57cec5SDimitry Andric    return __o->fetch_or(__op, __m);
2210*0b57cec5SDimitry Andric}
2211*0b57cec5SDimitry Andric
2212*0b57cec5SDimitry Andrictemplate <class _Tp>
2213*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2214*0b57cec5SDimitry Andrictypename enable_if
2215*0b57cec5SDimitry Andric<
2216*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2217*0b57cec5SDimitry Andric    _Tp
2218*0b57cec5SDimitry Andric>::type
2219*0b57cec5SDimitry Andricatomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2220*0b57cec5SDimitry Andric{
2221*0b57cec5SDimitry Andric    return __o->fetch_or(__op, __m);
2222*0b57cec5SDimitry Andric}
2223*0b57cec5SDimitry Andric
2224*0b57cec5SDimitry Andric// atomic_fetch_xor
2225*0b57cec5SDimitry Andric
2226*0b57cec5SDimitry Andrictemplate <class _Tp>
2227*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2228*0b57cec5SDimitry Andrictypename enable_if
2229*0b57cec5SDimitry Andric<
2230*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2231*0b57cec5SDimitry Andric    _Tp
2232*0b57cec5SDimitry Andric>::type
2233*0b57cec5SDimitry Andricatomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
2234*0b57cec5SDimitry Andric{
2235*0b57cec5SDimitry Andric    return __o->fetch_xor(__op);
2236*0b57cec5SDimitry Andric}
2237*0b57cec5SDimitry Andric
2238*0b57cec5SDimitry Andrictemplate <class _Tp>
2239*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2240*0b57cec5SDimitry Andrictypename enable_if
2241*0b57cec5SDimitry Andric<
2242*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2243*0b57cec5SDimitry Andric    _Tp
2244*0b57cec5SDimitry Andric>::type
2245*0b57cec5SDimitry Andricatomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
2246*0b57cec5SDimitry Andric{
2247*0b57cec5SDimitry Andric    return __o->fetch_xor(__op);
2248*0b57cec5SDimitry Andric}
2249*0b57cec5SDimitry Andric
2250*0b57cec5SDimitry Andric// atomic_fetch_xor_explicit
2251*0b57cec5SDimitry Andric
2252*0b57cec5SDimitry Andrictemplate <class _Tp>
2253*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2254*0b57cec5SDimitry Andrictypename enable_if
2255*0b57cec5SDimitry Andric<
2256*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2257*0b57cec5SDimitry Andric    _Tp
2258*0b57cec5SDimitry Andric>::type
2259*0b57cec5SDimitry Andricatomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2260*0b57cec5SDimitry Andric{
2261*0b57cec5SDimitry Andric    return __o->fetch_xor(__op, __m);
2262*0b57cec5SDimitry Andric}
2263*0b57cec5SDimitry Andric
2264*0b57cec5SDimitry Andrictemplate <class _Tp>
2265*0b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
2266*0b57cec5SDimitry Andrictypename enable_if
2267*0b57cec5SDimitry Andric<
2268*0b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
2269*0b57cec5SDimitry Andric    _Tp
2270*0b57cec5SDimitry Andric>::type
2271*0b57cec5SDimitry Andricatomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
2272*0b57cec5SDimitry Andric{
2273*0b57cec5SDimitry Andric    return __o->fetch_xor(__op, __m);
2274*0b57cec5SDimitry Andric}
2275*0b57cec5SDimitry Andric
2276*0b57cec5SDimitry Andric// flag type and operations
2277*0b57cec5SDimitry Andric
2278*0b57cec5SDimitry Andrictypedef struct atomic_flag
2279*0b57cec5SDimitry Andric{
2280*0b57cec5SDimitry Andric    __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
2281*0b57cec5SDimitry Andric
2282*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2283*0b57cec5SDimitry Andric    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
2284*0b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
2285*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2286*0b57cec5SDimitry Andric    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
2287*0b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
2288*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2289*0b57cec5SDimitry Andric    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
2290*0b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
2291*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2292*0b57cec5SDimitry Andric    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
2293*0b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
2294*0b57cec5SDimitry Andric
2295*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2296*0b57cec5SDimitry Andric    atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
2297*0b57cec5SDimitry Andric
2298*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
2299*0b57cec5SDimitry Andric    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
2300*0b57cec5SDimitry Andric
2301*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
2302*0b57cec5SDimitry Andric    atomic_flag(const atomic_flag&) = delete;
2303*0b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) = delete;
2304*0b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile = delete;
2305*0b57cec5SDimitry Andric#else
2306*0b57cec5SDimitry Andricprivate:
2307*0b57cec5SDimitry Andric    atomic_flag(const atomic_flag&);
2308*0b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&);
2309*0b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile;
2310*0b57cec5SDimitry Andric#endif
2311*0b57cec5SDimitry Andric} atomic_flag;
2312*0b57cec5SDimitry Andric
2313*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2314*0b57cec5SDimitry Andricbool
2315*0b57cec5SDimitry Andricatomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
2316*0b57cec5SDimitry Andric{
2317*0b57cec5SDimitry Andric    return __o->test_and_set();
2318*0b57cec5SDimitry Andric}
2319*0b57cec5SDimitry Andric
2320*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2321*0b57cec5SDimitry Andricbool
2322*0b57cec5SDimitry Andricatomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
2323*0b57cec5SDimitry Andric{
2324*0b57cec5SDimitry Andric    return __o->test_and_set();
2325*0b57cec5SDimitry Andric}
2326*0b57cec5SDimitry Andric
2327*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2328*0b57cec5SDimitry Andricbool
2329*0b57cec5SDimitry Andricatomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2330*0b57cec5SDimitry Andric{
2331*0b57cec5SDimitry Andric    return __o->test_and_set(__m);
2332*0b57cec5SDimitry Andric}
2333*0b57cec5SDimitry Andric
2334*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2335*0b57cec5SDimitry Andricbool
2336*0b57cec5SDimitry Andricatomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
2337*0b57cec5SDimitry Andric{
2338*0b57cec5SDimitry Andric    return __o->test_and_set(__m);
2339*0b57cec5SDimitry Andric}
2340*0b57cec5SDimitry Andric
2341*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2342*0b57cec5SDimitry Andricvoid
2343*0b57cec5SDimitry Andricatomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
2344*0b57cec5SDimitry Andric{
2345*0b57cec5SDimitry Andric    __o->clear();
2346*0b57cec5SDimitry Andric}
2347*0b57cec5SDimitry Andric
2348*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2349*0b57cec5SDimitry Andricvoid
2350*0b57cec5SDimitry Andricatomic_flag_clear(atomic_flag* __o) _NOEXCEPT
2351*0b57cec5SDimitry Andric{
2352*0b57cec5SDimitry Andric    __o->clear();
2353*0b57cec5SDimitry Andric}
2354*0b57cec5SDimitry Andric
2355*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2356*0b57cec5SDimitry Andricvoid
2357*0b57cec5SDimitry Andricatomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
2358*0b57cec5SDimitry Andric{
2359*0b57cec5SDimitry Andric    __o->clear(__m);
2360*0b57cec5SDimitry Andric}
2361*0b57cec5SDimitry Andric
2362*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2363*0b57cec5SDimitry Andricvoid
2364*0b57cec5SDimitry Andricatomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
2365*0b57cec5SDimitry Andric{
2366*0b57cec5SDimitry Andric    __o->clear(__m);
2367*0b57cec5SDimitry Andric}
2368*0b57cec5SDimitry Andric
2369*0b57cec5SDimitry Andric// fences
2370*0b57cec5SDimitry Andric
2371*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2372*0b57cec5SDimitry Andricvoid
2373*0b57cec5SDimitry Andricatomic_thread_fence(memory_order __m) _NOEXCEPT
2374*0b57cec5SDimitry Andric{
2375*0b57cec5SDimitry Andric    __cxx_atomic_thread_fence(__m);
2376*0b57cec5SDimitry Andric}
2377*0b57cec5SDimitry Andric
2378*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
2379*0b57cec5SDimitry Andricvoid
2380*0b57cec5SDimitry Andricatomic_signal_fence(memory_order __m) _NOEXCEPT
2381*0b57cec5SDimitry Andric{
2382*0b57cec5SDimitry Andric    __cxx_atomic_signal_fence(__m);
2383*0b57cec5SDimitry Andric}
2384*0b57cec5SDimitry Andric
2385*0b57cec5SDimitry Andric// Atomics for standard typedef types
2386*0b57cec5SDimitry Andric
2387*0b57cec5SDimitry Andrictypedef atomic<bool>               atomic_bool;
2388*0b57cec5SDimitry Andrictypedef atomic<char>               atomic_char;
2389*0b57cec5SDimitry Andrictypedef atomic<signed char>        atomic_schar;
2390*0b57cec5SDimitry Andrictypedef atomic<unsigned char>      atomic_uchar;
2391*0b57cec5SDimitry Andrictypedef atomic<short>              atomic_short;
2392*0b57cec5SDimitry Andrictypedef atomic<unsigned short>     atomic_ushort;
2393*0b57cec5SDimitry Andrictypedef atomic<int>                atomic_int;
2394*0b57cec5SDimitry Andrictypedef atomic<unsigned int>       atomic_uint;
2395*0b57cec5SDimitry Andrictypedef atomic<long>               atomic_long;
2396*0b57cec5SDimitry Andrictypedef atomic<unsigned long>      atomic_ulong;
2397*0b57cec5SDimitry Andrictypedef atomic<long long>          atomic_llong;
2398*0b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong;
2399*0b57cec5SDimitry Andrictypedef atomic<char16_t>           atomic_char16_t;
2400*0b57cec5SDimitry Andrictypedef atomic<char32_t>           atomic_char32_t;
2401*0b57cec5SDimitry Andrictypedef atomic<wchar_t>            atomic_wchar_t;
2402*0b57cec5SDimitry Andric
2403*0b57cec5SDimitry Andrictypedef atomic<int_least8_t>   atomic_int_least8_t;
2404*0b57cec5SDimitry Andrictypedef atomic<uint_least8_t>  atomic_uint_least8_t;
2405*0b57cec5SDimitry Andrictypedef atomic<int_least16_t>  atomic_int_least16_t;
2406*0b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t;
2407*0b57cec5SDimitry Andrictypedef atomic<int_least32_t>  atomic_int_least32_t;
2408*0b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t;
2409*0b57cec5SDimitry Andrictypedef atomic<int_least64_t>  atomic_int_least64_t;
2410*0b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t;
2411*0b57cec5SDimitry Andric
2412*0b57cec5SDimitry Andrictypedef atomic<int_fast8_t>   atomic_int_fast8_t;
2413*0b57cec5SDimitry Andrictypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
2414*0b57cec5SDimitry Andrictypedef atomic<int_fast16_t>  atomic_int_fast16_t;
2415*0b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
2416*0b57cec5SDimitry Andrictypedef atomic<int_fast32_t>  atomic_int_fast32_t;
2417*0b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
2418*0b57cec5SDimitry Andrictypedef atomic<int_fast64_t>  atomic_int_fast64_t;
2419*0b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
2420*0b57cec5SDimitry Andric
2421*0b57cec5SDimitry Andrictypedef atomic< int8_t>  atomic_int8_t;
2422*0b57cec5SDimitry Andrictypedef atomic<uint8_t>  atomic_uint8_t;
2423*0b57cec5SDimitry Andrictypedef atomic< int16_t> atomic_int16_t;
2424*0b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t;
2425*0b57cec5SDimitry Andrictypedef atomic< int32_t> atomic_int32_t;
2426*0b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t;
2427*0b57cec5SDimitry Andrictypedef atomic< int64_t> atomic_int64_t;
2428*0b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t;
2429*0b57cec5SDimitry Andric
2430*0b57cec5SDimitry Andrictypedef atomic<intptr_t>  atomic_intptr_t;
2431*0b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t;
2432*0b57cec5SDimitry Andrictypedef atomic<size_t>    atomic_size_t;
2433*0b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
2434*0b57cec5SDimitry Andrictypedef atomic<intmax_t>  atomic_intmax_t;
2435*0b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t;
2436*0b57cec5SDimitry Andric
2437*0b57cec5SDimitry Andric#define ATOMIC_FLAG_INIT {false}
2438*0b57cec5SDimitry Andric#define ATOMIC_VAR_INIT(__v) {__v}
2439*0b57cec5SDimitry Andric
2440*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
2441*0b57cec5SDimitry Andric
2442*0b57cec5SDimitry Andric#endif  // _LIBCPP_ATOMIC
2443