atomic revision 232924
1227825Stheraven// -*- C++ -*-
2227825Stheraven//===--------------------------- atomic -----------------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is distributed under the University of Illinois Open Source
7227825Stheraven// License. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP_ATOMIC
12227825Stheraven#define _LIBCPP_ATOMIC
13227825Stheraven
14227825Stheraven/*
15227825Stheraven    atomic synopsis
16227825Stheraven
17227825Stheravennamespace std
18227825Stheraven{
19227825Stheraven
20227825Stheraven// order and consistency
21227825Stheraven
22227825Stheraventypedef enum memory_order
23227825Stheraven{
24227825Stheraven    memory_order_relaxed,
25227825Stheraven    memory_order_consume,  // load-consume
26227825Stheraven    memory_order_acquire,  // load-acquire
27227825Stheraven    memory_order_release,  // store-release
28227825Stheraven    memory_order_acq_rel,  // store-release load-acquire
29227825Stheraven    memory_order_seq_cst   // store-release load-acquire
30227825Stheraven} memory_order;
31227825Stheraven
32227825Stheraventemplate <class T> T kill_dependency(T y);
33227825Stheraven
34227825Stheraven// lock-free property
35227825Stheraven
36227825Stheraven#define ATOMIC_CHAR_LOCK_FREE unspecified
37227825Stheraven#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
38227825Stheraven#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
39227825Stheraven#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
40227825Stheraven#define ATOMIC_SHORT_LOCK_FREE unspecified
41227825Stheraven#define ATOMIC_INT_LOCK_FREE unspecified
42227825Stheraven#define ATOMIC_LONG_LOCK_FREE unspecified
43227825Stheraven#define ATOMIC_LLONG_LOCK_FREE unspecified
44227825Stheraven
45227825Stheraven// flag type and operations
46227825Stheraven
47227825Stheraventypedef struct atomic_flag
48227825Stheraven{
49227825Stheraven    bool test_and_set(memory_order m = memory_order_seq_cst) volatile;
50227825Stheraven    bool test_and_set(memory_order m = memory_order_seq_cst);
51227825Stheraven    void clear(memory_order m = memory_order_seq_cst) volatile;
52227825Stheraven    void clear(memory_order m = memory_order_seq_cst);
53227825Stheraven    atomic_flag() = default;
54227825Stheraven    atomic_flag(const atomic_flag&) = delete;
55227825Stheraven    atomic_flag& operator=(const atomic_flag&) = delete;
56227825Stheraven    atomic_flag& operator=(const atomic_flag&) volatile = delete;
57227825Stheraven} atomic_flag;
58227825Stheraven
59227825Stheravenbool
60227825Stheraven    atomic_flag_test_and_set(volatile atomic_flag* obj);
61227825Stheraven
62227825Stheravenbool
63227825Stheraven    atomic_flag_test_and_set(atomic_flag* obj);
64227825Stheraven
65227825Stheravenbool
66227825Stheraven    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
67227825Stheraven                                      memory_order m);
68227825Stheraven
69227825Stheravenbool
70227825Stheraven    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m);
71227825Stheraven
72227825Stheravenvoid
73227825Stheraven    atomic_flag_clear(volatile atomic_flag* obj);
74227825Stheraven
75227825Stheravenvoid
76227825Stheraven    atomic_flag_clear(atomic_flag* obj);
77227825Stheraven
78227825Stheravenvoid
79227825Stheraven    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m);
80227825Stheraven
81227825Stheravenvoid
82227825Stheraven    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m);
83227825Stheraven
84227825Stheraven#define ATOMIC_FLAG_INIT see below
85227825Stheraven#define ATOMIC_VAR_INIT(value) see below
86227825Stheraven
87227825Stheraventemplate <class T>
88227825Stheravenstruct atomic
89227825Stheraven{
90227825Stheraven    bool is_lock_free() const volatile;
91227825Stheraven    bool is_lock_free() const;
92227825Stheraven    void store(T desr, memory_order m = memory_order_seq_cst) volatile;
93227825Stheraven    void store(T desr, memory_order m = memory_order_seq_cst);
94227825Stheraven    T load(memory_order m = memory_order_seq_cst) const volatile;
95227825Stheraven    T load(memory_order m = memory_order_seq_cst) const;
96227825Stheraven    operator T() const volatile;
97227825Stheraven    operator T() const;
98227825Stheraven    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile;
99227825Stheraven    T exchange(T desr, memory_order m = memory_order_seq_cst);
100227825Stheraven    bool compare_exchange_weak(T& expc, T desr,
101227825Stheraven                               memory_order s, memory_order f) volatile;
102227825Stheraven    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f);
103227825Stheraven    bool compare_exchange_strong(T& expc, T desr,
104227825Stheraven                                 memory_order s, memory_order f) volatile;
105227825Stheraven    bool compare_exchange_strong(T& expc, T desr,
106227825Stheraven                                 memory_order s, memory_order f);
107227825Stheraven    bool compare_exchange_weak(T& expc, T desr,
108227825Stheraven                               memory_order m = memory_order_seq_cst) volatile;
109227825Stheraven    bool compare_exchange_weak(T& expc, T desr,
110227825Stheraven                               memory_order m = memory_order_seq_cst);
111227825Stheraven    bool compare_exchange_strong(T& expc, T desr,
112227825Stheraven                                memory_order m = memory_order_seq_cst) volatile;
113227825Stheraven    bool compare_exchange_strong(T& expc, T desr,
114227825Stheraven                                 memory_order m = memory_order_seq_cst);
115227825Stheraven
116227825Stheraven    atomic() = default;
117227825Stheraven    constexpr atomic(T desr);
118227825Stheraven    atomic(const atomic&) = delete;
119227825Stheraven    atomic& operator=(const atomic&) = delete;
120227825Stheraven    atomic& operator=(const atomic&) volatile = delete;
121227825Stheraven    T operator=(T) volatile;
122227825Stheraven    T operator=(T);
123227825Stheraven};
124227825Stheraven
125227825Stheraventemplate <>
126227825Stheravenstruct atomic<integral>
127227825Stheraven{
128227825Stheraven    bool is_lock_free() const volatile;
129227825Stheraven    bool is_lock_free() const;
130227825Stheraven    void store(integral desr, memory_order m = memory_order_seq_cst) volatile;
131227825Stheraven    void store(integral desr, memory_order m = memory_order_seq_cst);
132227825Stheraven    integral load(memory_order m = memory_order_seq_cst) const volatile;
133227825Stheraven    integral load(memory_order m = memory_order_seq_cst) const;
134227825Stheraven    operator integral() const volatile;
135227825Stheraven    operator integral() const;
136227825Stheraven    integral exchange(integral desr,
137227825Stheraven                      memory_order m = memory_order_seq_cst) volatile;
138227825Stheraven    integral exchange(integral desr, memory_order m = memory_order_seq_cst);
139227825Stheraven    bool compare_exchange_weak(integral& expc, integral desr,
140227825Stheraven                               memory_order s, memory_order f) volatile;
141227825Stheraven    bool compare_exchange_weak(integral& expc, integral desr,
142227825Stheraven                               memory_order s, memory_order f);
143227825Stheraven    bool compare_exchange_strong(integral& expc, integral desr,
144227825Stheraven                                 memory_order s, memory_order f) volatile;
145227825Stheraven    bool compare_exchange_strong(integral& expc, integral desr,
146227825Stheraven                                 memory_order s, memory_order f);
147227825Stheraven    bool compare_exchange_weak(integral& expc, integral desr,
148227825Stheraven                               memory_order m = memory_order_seq_cst) volatile;
149227825Stheraven    bool compare_exchange_weak(integral& expc, integral desr,
150227825Stheraven                               memory_order m = memory_order_seq_cst);
151227825Stheraven    bool compare_exchange_strong(integral& expc, integral desr,
152227825Stheraven                                memory_order m = memory_order_seq_cst) volatile;
153227825Stheraven    bool compare_exchange_strong(integral& expc, integral desr,
154227825Stheraven                                 memory_order m = memory_order_seq_cst);
155227825Stheraven
156227825Stheraven    integral
157227825Stheraven        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile;
158227825Stheraven    integral fetch_add(integral op, memory_order m = memory_order_seq_cst);
159227825Stheraven    integral
160227825Stheraven        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile;
161227825Stheraven    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst);
162227825Stheraven    integral
163227825Stheraven        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile;
164227825Stheraven    integral fetch_and(integral op, memory_order m = memory_order_seq_cst);
165227825Stheraven    integral
166227825Stheraven        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile;
167227825Stheraven    integral fetch_or(integral op, memory_order m = memory_order_seq_cst);
168227825Stheraven    integral
169227825Stheraven        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile;
170227825Stheraven    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst);
171227825Stheraven
172227825Stheraven    atomic() = default;
173227825Stheraven    constexpr atomic(integral desr);
174227825Stheraven    atomic(const atomic&) = delete;
175227825Stheraven    atomic& operator=(const atomic&) = delete;
176227825Stheraven    atomic& operator=(const atomic&) volatile = delete;
177227825Stheraven    integral operator=(integral desr) volatile;
178227825Stheraven    integral operator=(integral desr);
179227825Stheraven
180227825Stheraven    integral operator++(int) volatile;
181227825Stheraven    integral operator++(int);
182227825Stheraven    integral operator--(int) volatile;
183227825Stheraven    integral operator--(int);
184227825Stheraven    integral operator++() volatile;
185227825Stheraven    integral operator++();
186227825Stheraven    integral operator--() volatile;
187227825Stheraven    integral operator--();
188227825Stheraven    integral operator+=(integral op) volatile;
189227825Stheraven    integral operator+=(integral op);
190227825Stheraven    integral operator-=(integral op) volatile;
191227825Stheraven    integral operator-=(integral op);
192227825Stheraven    integral operator&=(integral op) volatile;
193227825Stheraven    integral operator&=(integral op);
194227825Stheraven    integral operator|=(integral op) volatile;
195227825Stheraven    integral operator|=(integral op);
196227825Stheraven    integral operator^=(integral op) volatile;
197227825Stheraven    integral operator^=(integral op);
198227825Stheraven};
199227825Stheraven
200227825Stheraventemplate <class T>
201227825Stheravenstruct atomic<T*>
202227825Stheraven{
203227825Stheraven    bool is_lock_free() const volatile;
204227825Stheraven    bool is_lock_free() const;
205227825Stheraven    void store(T* desr, memory_order m = memory_order_seq_cst) volatile;
206227825Stheraven    void store(T* desr, memory_order m = memory_order_seq_cst);
207227825Stheraven    T* load(memory_order m = memory_order_seq_cst) const volatile;
208227825Stheraven    T* load(memory_order m = memory_order_seq_cst) const;
209227825Stheraven    operator T*() const volatile;
210227825Stheraven    operator T*() const;
211227825Stheraven    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile;
212227825Stheraven    T* exchange(T* desr, memory_order m = memory_order_seq_cst);
213227825Stheraven    bool compare_exchange_weak(T*& expc, T* desr,
214227825Stheraven                               memory_order s, memory_order f) volatile;
215227825Stheraven    bool compare_exchange_weak(T*& expc, T* desr,
216227825Stheraven                               memory_order s, memory_order f);
217227825Stheraven    bool compare_exchange_strong(T*& expc, T* desr,
218227825Stheraven                                 memory_order s, memory_order f) volatile;
219227825Stheraven    bool compare_exchange_strong(T*& expc, T* desr,
220227825Stheraven                                 memory_order s, memory_order f);
221227825Stheraven    bool compare_exchange_weak(T*& expc, T* desr,
222227825Stheraven                               memory_order m = memory_order_seq_cst) volatile;
223227825Stheraven    bool compare_exchange_weak(T*& expc, T* desr,
224227825Stheraven                               memory_order m = memory_order_seq_cst);
225227825Stheraven    bool compare_exchange_strong(T*& expc, T* desr,
226227825Stheraven                                memory_order m = memory_order_seq_cst) volatile;
227227825Stheraven    bool compare_exchange_strong(T*& expc, T* desr,
228227825Stheraven                                 memory_order m = memory_order_seq_cst);
229227825Stheraven    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile;
230227825Stheraven    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst);
231227825Stheraven    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile;
232227825Stheraven    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst);
233227825Stheraven
234227825Stheraven    atomic() = default;
235227825Stheraven    constexpr atomic(T* desr);
236227825Stheraven    atomic(const atomic&) = delete;
237227825Stheraven    atomic& operator=(const atomic&) = delete;
238227825Stheraven    atomic& operator=(const atomic&) volatile = delete;
239227825Stheraven
240227825Stheraven    T* operator=(T*) volatile;
241227825Stheraven    T* operator=(T*);
242227825Stheraven    T* operator++(int) volatile;
243227825Stheraven    T* operator++(int);
244227825Stheraven    T* operator--(int) volatile;
245227825Stheraven    T* operator--(int);
246227825Stheraven    T* operator++() volatile;
247227825Stheraven    T* operator++();
248227825Stheraven    T* operator--() volatile;
249227825Stheraven    T* operator--();
250227825Stheraven    T* operator+=(ptrdiff_t op) volatile;
251227825Stheraven    T* operator+=(ptrdiff_t op);
252227825Stheraven    T* operator-=(ptrdiff_t op) volatile;
253227825Stheraven    T* operator-=(ptrdiff_t op);
254227825Stheraven};
255227825Stheraven
256227825Stheraven
257227825Stheraventemplate <class T>
258227825Stheraven    bool
259227825Stheraven    atomic_is_lock_free(const volatile atomic<T>* obj);
260227825Stheraven
261227825Stheraventemplate <class T>
262227825Stheraven    bool
263227825Stheraven    atomic_is_lock_free(const atomic<T>* obj);
264227825Stheraven
265227825Stheraventemplate <class T>
266227825Stheraven    void
267227825Stheraven    atomic_init(volatile atomic<T>* obj, T desr);
268227825Stheraven
269227825Stheraventemplate <class T>
270227825Stheraven    void
271227825Stheraven    atomic_init(atomic<T>* obj, T desr);
272227825Stheraven
273227825Stheraventemplate <class T>
274227825Stheraven    void
275227825Stheraven    atomic_store(volatile atomic<T>* obj, T desr);
276227825Stheraven
277227825Stheraventemplate <class T>
278227825Stheraven    void
279227825Stheraven    atomic_store(atomic<T>* obj, T desr);
280227825Stheraven
281227825Stheraventemplate <class T>
282227825Stheraven    void
283227825Stheraven    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m);
284227825Stheraven
285227825Stheraventemplate <class T>
286227825Stheraven    void
287227825Stheraven    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m);
288227825Stheraven
289227825Stheraventemplate <class T>
290227825Stheraven    T
291227825Stheraven    atomic_load(const volatile atomic<T>* obj);
292227825Stheraven
293227825Stheraventemplate <class T>
294227825Stheraven    T
295227825Stheraven    atomic_load(const atomic<T>* obj);
296227825Stheraven
297227825Stheraventemplate <class T>
298227825Stheraven    T
299227825Stheraven    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m);
300227825Stheraven
301227825Stheraventemplate <class T>
302227825Stheraven    T
303227825Stheraven    atomic_load_explicit(const atomic<T>* obj, memory_order m);
304227825Stheraven
305227825Stheraventemplate <class T>
306227825Stheraven    T
307227825Stheraven    atomic_exchange(volatile atomic<T>* obj, T desr);
308227825Stheraven
309227825Stheraventemplate <class T>
310227825Stheraven    T
311227825Stheraven    atomic_exchange(atomic<T>* obj, T desr);
312227825Stheraven
313227825Stheraventemplate <class T>
314227825Stheraven    T
315227825Stheraven    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m);
316227825Stheraven
317227825Stheraventemplate <class T>
318227825Stheraven    T
319227825Stheraven    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m);
320227825Stheraven
321227825Stheraventemplate <class T>
322227825Stheraven    bool
323227825Stheraven    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr);
324227825Stheraven
325227825Stheraventemplate <class T>
326227825Stheraven    bool
327227825Stheraven    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr);
328227825Stheraven
329227825Stheraventemplate <class T>
330227825Stheraven    bool
331227825Stheraven    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr);
332227825Stheraven
333227825Stheraventemplate <class T>
334227825Stheraven    bool
335227825Stheraven    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr);
336227825Stheraven
337227825Stheraventemplate <class T>
338227825Stheraven    bool
339227825Stheraven    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
340227825Stheraven                                          T desr,
341227825Stheraven                                          memory_order s, memory_order f);
342227825Stheraven
343227825Stheraventemplate <class T>
344227825Stheraven    bool
345227825Stheraven    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
346227825Stheraven                                          memory_order s, memory_order f);
347227825Stheraven
348227825Stheraventemplate <class T>
349227825Stheraven    bool
350227825Stheraven    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
351227825Stheraven                                            T* expc, T desr,
352227825Stheraven                                            memory_order s, memory_order f);
353227825Stheraven
354227825Stheraventemplate <class T>
355227825Stheraven    bool
356227825Stheraven    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
357227825Stheraven                                            T desr,
358227825Stheraven                                            memory_order s, memory_order f);
359227825Stheraven
360227825Stheraventemplate <class Integral>
361227825Stheraven    Integral
362227825Stheraven    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op);
363227825Stheraven
364227825Stheraventemplate <class Integral>
365227825Stheraven    Integral
366227825Stheraven    atomic_fetch_add(atomic<Integral>* obj, Integral op);
367227825Stheraven
368227825Stheraventemplate <class Integral>
369227825Stheraven    Integral
370227825Stheraven    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
371227825Stheraven                              memory_order m);
372227825Stheraventemplate <class Integral>
373227825Stheraven    Integral
374227825Stheraven    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
375227825Stheraven                              memory_order m);
376227825Stheraventemplate <class Integral>
377227825Stheraven    Integral
378227825Stheraven    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op);
379227825Stheraven
380227825Stheraventemplate <class Integral>
381227825Stheraven    Integral
382227825Stheraven    atomic_fetch_sub(atomic<Integral>* obj, Integral op);
383227825Stheraven
384227825Stheraventemplate <class Integral>
385227825Stheraven    Integral
386227825Stheraven    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
387227825Stheraven                              memory_order m);
388227825Stheraventemplate <class Integral>
389227825Stheraven    Integral
390227825Stheraven    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
391227825Stheraven                              memory_order m);
392227825Stheraventemplate <class Integral>
393227825Stheraven    Integral
394227825Stheraven    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op);
395227825Stheraven
396227825Stheraventemplate <class Integral>
397227825Stheraven    Integral
398227825Stheraven    atomic_fetch_and(atomic<Integral>* obj, Integral op);
399227825Stheraven
400227825Stheraventemplate <class Integral>
401227825Stheraven    Integral
402227825Stheraven    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
403227825Stheraven                              memory_order m);
404227825Stheraventemplate <class Integral>
405227825Stheraven    Integral
406227825Stheraven    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
407227825Stheraven                              memory_order m);
408227825Stheraventemplate <class Integral>
409227825Stheraven    Integral
410227825Stheraven    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op);
411227825Stheraven
412227825Stheraventemplate <class Integral>
413227825Stheraven    Integral
414227825Stheraven    atomic_fetch_or(atomic<Integral>* obj, Integral op);
415227825Stheraven
416227825Stheraventemplate <class Integral>
417227825Stheraven    Integral
418227825Stheraven    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
419227825Stheraven                             memory_order m);
420227825Stheraventemplate <class Integral>
421227825Stheraven    Integral
422227825Stheraven    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
423227825Stheraven                             memory_order m);
424227825Stheraventemplate <class Integral>
425227825Stheraven    Integral
426227825Stheraven    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op);
427227825Stheraven
428227825Stheraventemplate <class Integral>
429227825Stheraven    Integral
430227825Stheraven    atomic_fetch_xor(atomic<Integral>* obj, Integral op);
431227825Stheraven
432227825Stheraventemplate <class Integral>
433227825Stheraven    Integral
434227825Stheraven    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
435227825Stheraven                              memory_order m);
436227825Stheraventemplate <class Integral>
437227825Stheraven    Integral
438227825Stheraven    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
439227825Stheraven                              memory_order m);
440227825Stheraven
441227825Stheraventemplate <class T>
442227825Stheraven    T*
443227825Stheraven    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op);
444227825Stheraven
445227825Stheraventemplate <class T>
446227825Stheraven    T*
447227825Stheraven    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op);
448227825Stheraven
449227825Stheraventemplate <class T>
450227825Stheraven    T*
451227825Stheraven    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
452227825Stheraven                              memory_order m);
453227825Stheraventemplate <class T>
454227825Stheraven    T*
455227825Stheraven    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m);
456227825Stheraven
457227825Stheraventemplate <class T>
458227825Stheraven    T*
459227825Stheraven    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op);
460227825Stheraven
461227825Stheraventemplate <class T>
462227825Stheraven    T*
463227825Stheraven    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op);
464227825Stheraven
465227825Stheraventemplate <class T>
466227825Stheraven    T*
467227825Stheraven    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
468227825Stheraven                              memory_order m);
469227825Stheraventemplate <class T>
470227825Stheraven    T*
471227825Stheraven    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m);
472227825Stheraven
473227825Stheraven// Atomics for standard typedef types
474227825Stheraven
475227825Stheraventypedef atomic<char>               atomic_char;
476227825Stheraventypedef atomic<signed char>        atomic_schar;
477227825Stheraventypedef atomic<unsigned char>      atomic_uchar;
478227825Stheraventypedef atomic<short>              atomic_short;
479227825Stheraventypedef atomic<unsigned short>     atomic_ushort;
480227825Stheraventypedef atomic<int>                atomic_int;
481227825Stheraventypedef atomic<unsigned int>       atomic_uint;
482227825Stheraventypedef atomic<long>               atomic_long;
483227825Stheraventypedef atomic<unsigned long>      atomic_ulong;
484227825Stheraventypedef atomic<long long>          atomic_llong;
485227825Stheraventypedef atomic<unsigned long long> atomic_ullong;
486227825Stheraventypedef atomic<char16_t>           atomic_char16_t;
487227825Stheraventypedef atomic<char32_t>           atomic_char32_t;
488227825Stheraventypedef atomic<wchar_t>            atomic_wchar_t;
489227825Stheraven
490227825Stheraventypedef atomic<int_least8_t>   atomic_int_least8_t;
491227825Stheraventypedef atomic<uint_least8_t>  atomic_uint_least8_t;
492227825Stheraventypedef atomic<int_least16_t>  atomic_int_least16_t;
493227825Stheraventypedef atomic<uint_least16_t> atomic_uint_least16_t;
494227825Stheraventypedef atomic<int_least32_t>  atomic_int_least32_t;
495227825Stheraventypedef atomic<uint_least32_t> atomic_uint_least32_t;
496227825Stheraventypedef atomic<int_least64_t>  atomic_int_least64_t;
497227825Stheraventypedef atomic<uint_least64_t> atomic_uint_least64_t;
498227825Stheraven
499227825Stheraventypedef atomic<int_fast8_t>   atomic_int_fast8_t;
500227825Stheraventypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
501227825Stheraventypedef atomic<int_fast16_t>  atomic_int_fast16_t;
502227825Stheraventypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
503227825Stheraventypedef atomic<int_fast32_t>  atomic_int_fast32_t;
504227825Stheraventypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
505227825Stheraventypedef atomic<int_fast64_t>  atomic_int_fast64_t;
506227825Stheraventypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
507227825Stheraven
508227825Stheraventypedef atomic<intptr_t>  atomic_intptr_t;
509227825Stheraventypedef atomic<uintptr_t> atomic_uintptr_t;
510227825Stheraventypedef atomic<size_t>    atomic_size_t;
511227825Stheraventypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
512227825Stheraventypedef atomic<intmax_t>  atomic_intmax_t;
513227825Stheraventypedef atomic<uintmax_t> atomic_uintmax_t;
514227825Stheraven
515227825Stheraven// fences
516227825Stheraven
517227825Stheravenvoid atomic_thread_fence(memory_order m);
518227825Stheravenvoid atomic_signal_fence(memory_order m);
519227825Stheraven
520227825Stheraven}  // std
521227825Stheraven
522227825Stheraven*/
523227825Stheraven
524227825Stheraven#include <__config>
525227825Stheraven#include <cstddef>
526227825Stheraven#include <cstdint>
527227825Stheraven#include <type_traits>
528227825Stheraven
529227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
530227825Stheraven#pragma GCC system_header
531227825Stheraven#endif
532227825Stheraven
533227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
534227825Stheraven
535227825Stheraven#if !__has_feature(cxx_atomic)
536227825Stheraven#error <atomic> is not implemented
537227825Stheraven#else
538227825Stheraven
539227825Stheraventypedef enum memory_order
540227825Stheraven{
541227825Stheraven    memory_order_relaxed, memory_order_consume, memory_order_acquire,
542227825Stheraven    memory_order_release, memory_order_acq_rel, memory_order_seq_cst
543227825Stheraven} memory_order;
544227825Stheraven
545227825Stheraventemplate <class _Tp>
546227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
547227825Stheraven_Tp
548227825Stheravenkill_dependency(_Tp __y)
549227825Stheraven{
550227825Stheraven    return __y;
551227825Stheraven}
552227825Stheraven
553227825Stheraven// general atomic<T>
554227825Stheraven
555227825Stheraventemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
556227825Stheravenstruct __atomic_base  // false
557227825Stheraven{
558232924Stheraven    _Atomic(_Tp) __a_;
559227825Stheraven
560227825Stheraven    _LIBCPP_INLINE_VISIBILITY
561227825Stheraven    bool is_lock_free() const volatile
562227825Stheraven        {return __atomic_is_lock_free(_Tp());}
563227825Stheraven    _LIBCPP_INLINE_VISIBILITY
564227825Stheraven    bool is_lock_free() const
565227825Stheraven        {return __atomic_is_lock_free(_Tp());}
566227825Stheraven    _LIBCPP_INLINE_VISIBILITY
567227825Stheraven    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile
568227825Stheraven        {__atomic_store(&__a_, __d, __m);}
569227825Stheraven    _LIBCPP_INLINE_VISIBILITY
570227825Stheraven    void store(_Tp __d, memory_order __m = memory_order_seq_cst)
571227825Stheraven        {__atomic_store(&__a_, __d, __m);}
572227825Stheraven    _LIBCPP_INLINE_VISIBILITY
573227825Stheraven    _Tp load(memory_order __m = memory_order_seq_cst) const volatile
574227825Stheraven        {return __atomic_load(&__a_, __m);}
575227825Stheraven    _LIBCPP_INLINE_VISIBILITY
576227825Stheraven    _Tp load(memory_order __m = memory_order_seq_cst) const
577227825Stheraven        {return __atomic_load(&__a_, __m);}
578227825Stheraven    _LIBCPP_INLINE_VISIBILITY
579227825Stheraven    operator _Tp() const volatile {return load();}
580227825Stheraven    _LIBCPP_INLINE_VISIBILITY
581227825Stheraven    operator _Tp() const          {return load();}
582227825Stheraven    _LIBCPP_INLINE_VISIBILITY
583227825Stheraven    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile
584227825Stheraven        {return __atomic_exchange(&__a_, __d, __m);}
585227825Stheraven    _LIBCPP_INLINE_VISIBILITY
586227825Stheraven    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst)
587227825Stheraven        {return __atomic_exchange(&__a_, __d, __m);}
588227825Stheraven    _LIBCPP_INLINE_VISIBILITY
589227825Stheraven    bool compare_exchange_weak(_Tp& __e, _Tp __d,
590227825Stheraven                               memory_order __s, memory_order __f) volatile
591227825Stheraven        {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
592227825Stheraven    _LIBCPP_INLINE_VISIBILITY
593227825Stheraven    bool compare_exchange_weak(_Tp& __e, _Tp __d,
594227825Stheraven                               memory_order __s, memory_order __f)
595227825Stheraven        {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
596227825Stheraven    _LIBCPP_INLINE_VISIBILITY
597227825Stheraven    bool compare_exchange_strong(_Tp& __e, _Tp __d,
598227825Stheraven                                 memory_order __s, memory_order __f) volatile
599227825Stheraven        {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
600227825Stheraven    _LIBCPP_INLINE_VISIBILITY
601227825Stheraven    bool compare_exchange_strong(_Tp& __e, _Tp __d,
602227825Stheraven                                 memory_order __s, memory_order __f)
603227825Stheraven        {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
604227825Stheraven    _LIBCPP_INLINE_VISIBILITY
605227825Stheraven    bool compare_exchange_weak(_Tp& __e, _Tp __d,
606227825Stheraven                              memory_order __m = memory_order_seq_cst) volatile
607227825Stheraven        {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
608227825Stheraven    _LIBCPP_INLINE_VISIBILITY
609227825Stheraven    bool compare_exchange_weak(_Tp& __e, _Tp __d,
610227825Stheraven                               memory_order __m = memory_order_seq_cst)
611227825Stheraven        {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
612227825Stheraven    _LIBCPP_INLINE_VISIBILITY
613227825Stheraven    bool compare_exchange_strong(_Tp& __e, _Tp __d,
614227825Stheraven                              memory_order __m = memory_order_seq_cst) volatile
615227825Stheraven        {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
616227825Stheraven    _LIBCPP_INLINE_VISIBILITY
617227825Stheraven    bool compare_exchange_strong(_Tp& __e, _Tp __d,
618227825Stheraven                                 memory_order __m = memory_order_seq_cst)
619227825Stheraven        {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
620227825Stheraven
621227825Stheraven    _LIBCPP_INLINE_VISIBILITY
622227825Stheraven    __atomic_base() {} // = default;
623227825Stheraven    _LIBCPP_INLINE_VISIBILITY
624232924Stheraven    /*constexpr*/ __atomic_base(_Tp __d) { __atomic_store(&__a_, __d, memory_order_seq_cst); }
625227825Stheraven#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
626227825Stheraven    __atomic_base(const __atomic_base&) = delete;
627227825Stheraven    __atomic_base& operator=(const __atomic_base&) = delete;
628227825Stheraven    __atomic_base& operator=(const __atomic_base&) volatile = delete;
629227825Stheraven#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
630227825Stheravenprivate:
631227825Stheraven    __atomic_base(const __atomic_base&);
632227825Stheraven    __atomic_base& operator=(const __atomic_base&);
633227825Stheraven    __atomic_base& operator=(const __atomic_base&) volatile;
634227825Stheraven#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
635227825Stheraven};
636227825Stheraven
637227825Stheraven// atomic<Integral>
638227825Stheraven
639227825Stheraventemplate <class _Tp>
640227825Stheravenstruct __atomic_base<_Tp, true>
641227825Stheraven    : public __atomic_base<_Tp, false>
642227825Stheraven{
643227825Stheraven    typedef __atomic_base<_Tp, false> __base;
644227825Stheraven    _LIBCPP_INLINE_VISIBILITY
645227825Stheraven    __atomic_base() {} // = default;
646227825Stheraven    _LIBCPP_INLINE_VISIBILITY
647227825Stheraven    /*constexpr*/ __atomic_base(_Tp __d) : __base(__d) {}
648227825Stheraven
649227825Stheraven    _LIBCPP_INLINE_VISIBILITY
650227825Stheraven    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
651227825Stheraven        {return __atomic_fetch_add(&this->__a_, __op, __m);}
652227825Stheraven    _LIBCPP_INLINE_VISIBILITY
653227825Stheraven    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst)
654227825Stheraven        {return __atomic_fetch_add(&this->__a_, __op, __m);}
655227825Stheraven    _LIBCPP_INLINE_VISIBILITY
656227825Stheraven    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
657227825Stheraven        {return __atomic_fetch_sub(&this->__a_, __op, __m);}
658227825Stheraven    _LIBCPP_INLINE_VISIBILITY
659227825Stheraven    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst)
660227825Stheraven        {return __atomic_fetch_sub(&this->__a_, __op, __m);}
661227825Stheraven    _LIBCPP_INLINE_VISIBILITY
662227825Stheraven    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
663227825Stheraven        {return __atomic_fetch_and(&this->__a_, __op, __m);}
664227825Stheraven    _LIBCPP_INLINE_VISIBILITY
665227825Stheraven    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst)
666227825Stheraven        {return __atomic_fetch_and(&this->__a_, __op, __m);}
667227825Stheraven    _LIBCPP_INLINE_VISIBILITY
668227825Stheraven    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
669227825Stheraven        {return __atomic_fetch_or(&this->__a_, __op, __m);}
670227825Stheraven    _LIBCPP_INLINE_VISIBILITY
671227825Stheraven    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst)
672227825Stheraven        {return __atomic_fetch_or(&this->__a_, __op, __m);}
673227825Stheraven    _LIBCPP_INLINE_VISIBILITY
674227825Stheraven    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
675227825Stheraven        {return __atomic_fetch_xor(&this->__a_, __op, __m);}
676227825Stheraven    _LIBCPP_INLINE_VISIBILITY
677227825Stheraven    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst)
678227825Stheraven        {return __atomic_fetch_xor(&this->__a_, __op, __m);}
679227825Stheraven
680227825Stheraven    _LIBCPP_INLINE_VISIBILITY
681227825Stheraven    _Tp operator++(int) volatile      {return fetch_add(_Tp(1));}
682227825Stheraven    _LIBCPP_INLINE_VISIBILITY
683227825Stheraven    _Tp operator++(int)               {return fetch_add(_Tp(1));}
684227825Stheraven    _LIBCPP_INLINE_VISIBILITY
685227825Stheraven    _Tp operator--(int) volatile      {return fetch_sub(_Tp(1));}
686227825Stheraven    _LIBCPP_INLINE_VISIBILITY
687227825Stheraven    _Tp operator--(int)               {return fetch_sub(_Tp(1));}
688227825Stheraven    _LIBCPP_INLINE_VISIBILITY
689227825Stheraven    _Tp operator++() volatile         {return fetch_add(_Tp(1)) + _Tp(1);}
690227825Stheraven    _LIBCPP_INLINE_VISIBILITY
691227825Stheraven    _Tp operator++()                  {return fetch_add(_Tp(1)) + _Tp(1);}
692227825Stheraven    _LIBCPP_INLINE_VISIBILITY
693227825Stheraven    _Tp operator--() volatile         {return fetch_sub(_Tp(1)) - _Tp(1);}
694227825Stheraven    _LIBCPP_INLINE_VISIBILITY
695227825Stheraven    _Tp operator--()                  {return fetch_sub(_Tp(1)) - _Tp(1);}
696227825Stheraven    _LIBCPP_INLINE_VISIBILITY
697227825Stheraven    _Tp operator+=(_Tp __op) volatile {return fetch_add(__op) + __op;}
698227825Stheraven    _LIBCPP_INLINE_VISIBILITY
699227825Stheraven    _Tp operator+=(_Tp __op)          {return fetch_add(__op) + __op;}
700227825Stheraven    _LIBCPP_INLINE_VISIBILITY
701227825Stheraven    _Tp operator-=(_Tp __op) volatile {return fetch_sub(__op) - __op;}
702227825Stheraven    _LIBCPP_INLINE_VISIBILITY
703227825Stheraven    _Tp operator-=(_Tp __op)          {return fetch_sub(__op) - __op;}
704227825Stheraven    _LIBCPP_INLINE_VISIBILITY
705227825Stheraven    _Tp operator&=(_Tp __op) volatile {return fetch_and(__op) & __op;}
706227825Stheraven    _LIBCPP_INLINE_VISIBILITY
707227825Stheraven    _Tp operator&=(_Tp __op)          {return fetch_and(__op) & __op;}
708227825Stheraven    _LIBCPP_INLINE_VISIBILITY
709227825Stheraven    _Tp operator|=(_Tp __op) volatile {return fetch_or(__op) | __op;}
710227825Stheraven    _LIBCPP_INLINE_VISIBILITY
711227825Stheraven    _Tp operator|=(_Tp __op)          {return fetch_or(__op) | __op;}
712227825Stheraven    _LIBCPP_INLINE_VISIBILITY
713227825Stheraven    _Tp operator^=(_Tp __op) volatile {return fetch_xor(__op) ^ __op;}
714227825Stheraven    _LIBCPP_INLINE_VISIBILITY
715227825Stheraven    _Tp operator^=(_Tp __op)          {return fetch_xor(__op) ^ __op;}
716227825Stheraven};
717227825Stheraven
718227825Stheraven// atomic<T>
719227825Stheraven
720227825Stheraventemplate <class _Tp>
721227825Stheravenstruct atomic
722227825Stheraven    : public __atomic_base<_Tp>
723227825Stheraven{
724227825Stheraven    typedef __atomic_base<_Tp> __base;
725227825Stheraven    _LIBCPP_INLINE_VISIBILITY
726227825Stheraven    atomic() {} // = default;
727227825Stheraven    _LIBCPP_INLINE_VISIBILITY
728227825Stheraven    /*constexpr*/ atomic(_Tp __d) : __base(__d) {}
729227825Stheraven
730227825Stheraven    _LIBCPP_INLINE_VISIBILITY
731227825Stheraven    _Tp operator=(_Tp __d) volatile
732227825Stheraven        {__base::store(__d); return __d;}
733227825Stheraven    _LIBCPP_INLINE_VISIBILITY
734227825Stheraven    _Tp operator=(_Tp __d)
735227825Stheraven        {__base::store(__d); return __d;}
736227825Stheraven};
737227825Stheraven
738227825Stheraven// atomic<T*>
739227825Stheraven
740227825Stheraventemplate <class _Tp>
741227825Stheravenstruct atomic<_Tp*>
742227825Stheraven    : public __atomic_base<_Tp*>
743227825Stheraven{
744227825Stheraven    typedef __atomic_base<_Tp*> __base;
745227825Stheraven    _LIBCPP_INLINE_VISIBILITY
746227825Stheraven    atomic() {} // = default;
747227825Stheraven    _LIBCPP_INLINE_VISIBILITY
748227825Stheraven    /*constexpr*/ atomic(_Tp* __d) : __base(__d) {}
749227825Stheraven
750227825Stheraven    _LIBCPP_INLINE_VISIBILITY
751227825Stheraven    _Tp* operator=(_Tp* __d) volatile
752227825Stheraven        {__base::store(__d); return __d;}
753227825Stheraven    _LIBCPP_INLINE_VISIBILITY
754227825Stheraven    _Tp* operator=(_Tp* __d)
755227825Stheraven        {__base::store(__d); return __d;}
756227825Stheraven
757227825Stheraven    _LIBCPP_INLINE_VISIBILITY
758227825Stheraven    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
759227825Stheraven                                                                        volatile
760227825Stheraven        {return __atomic_fetch_add(&this->__a_, __op, __m);}
761227825Stheraven    _LIBCPP_INLINE_VISIBILITY
762227825Stheraven    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
763227825Stheraven        {return __atomic_fetch_add(&this->__a_, __op, __m);}
764227825Stheraven    _LIBCPP_INLINE_VISIBILITY
765227825Stheraven    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
766227825Stheraven                                                                        volatile
767227825Stheraven        {return __atomic_fetch_sub(&this->__a_, __op, __m);}
768227825Stheraven    _LIBCPP_INLINE_VISIBILITY
769227825Stheraven    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
770227825Stheraven        {return __atomic_fetch_sub(&this->__a_, __op, __m);}
771227825Stheraven
772227825Stheraven    _LIBCPP_INLINE_VISIBILITY
773227825Stheraven    _Tp* operator++(int) volatile            {return fetch_add(1);}
774227825Stheraven    _LIBCPP_INLINE_VISIBILITY
775227825Stheraven    _Tp* operator++(int)                     {return fetch_add(1);}
776227825Stheraven    _LIBCPP_INLINE_VISIBILITY
777227825Stheraven    _Tp* operator--(int) volatile            {return fetch_sub(1);}
778227825Stheraven    _LIBCPP_INLINE_VISIBILITY
779227825Stheraven    _Tp* operator--(int)                     {return fetch_sub(1);}
780227825Stheraven    _LIBCPP_INLINE_VISIBILITY
781227825Stheraven    _Tp* operator++() volatile               {return fetch_add(1) + 1;}
782227825Stheraven    _LIBCPP_INLINE_VISIBILITY
783227825Stheraven    _Tp* operator++()                        {return fetch_add(1) + 1;}
784227825Stheraven    _LIBCPP_INLINE_VISIBILITY
785227825Stheraven    _Tp* operator--() volatile               {return fetch_sub(1) - 1;}
786227825Stheraven    _LIBCPP_INLINE_VISIBILITY
787227825Stheraven    _Tp* operator--()                        {return fetch_sub(1) - 1;}
788227825Stheraven    _LIBCPP_INLINE_VISIBILITY
789227825Stheraven    _Tp* operator+=(ptrdiff_t __op) volatile {return fetch_add(__op) + __op;}
790227825Stheraven    _LIBCPP_INLINE_VISIBILITY
791227825Stheraven    _Tp* operator+=(ptrdiff_t __op)          {return fetch_add(__op) + __op;}
792227825Stheraven    _LIBCPP_INLINE_VISIBILITY
793227825Stheraven    _Tp* operator-=(ptrdiff_t __op) volatile {return fetch_sub(__op) - __op;}
794227825Stheraven    _LIBCPP_INLINE_VISIBILITY
795227825Stheraven    _Tp* operator-=(ptrdiff_t __op)          {return fetch_sub(__op) - __op;}
796227825Stheraven};
797227825Stheraven
798227825Stheraven// atomic_is_lock_free
799227825Stheraven
800227825Stheraventemplate <class _Tp>
801227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
802227825Stheravenbool
803227825Stheravenatomic_is_lock_free(const volatile atomic<_Tp>* __o)
804227825Stheraven{
805227825Stheraven    return __o->is_lock_free();
806227825Stheraven}
807227825Stheraven
808227825Stheraventemplate <class _Tp>
809227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
810227825Stheravenbool
811227825Stheravenatomic_is_lock_free(const atomic<_Tp>* __o)
812227825Stheraven{
813227825Stheraven    return __o->is_lock_free();
814227825Stheraven}
815227825Stheraven
816227825Stheraven// atomic_init
817227825Stheraven
818227825Stheraventemplate <class _Tp>
819227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
820227825Stheravenvoid
821227825Stheravenatomic_init(volatile atomic<_Tp>* __o, _Tp __d)
822227825Stheraven{
823232924Stheraven    __atomic_store(&__o->__a_, __d, memory_order_seq_cst);
824227825Stheraven}
825227825Stheraven
826227825Stheraventemplate <class _Tp>
827227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
828227825Stheravenvoid
829227825Stheravenatomic_init(atomic<_Tp>* __o, _Tp __d)
830227825Stheraven{
831232924Stheraven    __atomic_store(&__o->__a_, __d, memory_order_seq_cst);
832227825Stheraven}
833227825Stheraven
834227825Stheraven// atomic_store
835227825Stheraven
836227825Stheraventemplate <class _Tp>
837227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
838227825Stheravenvoid
839227825Stheravenatomic_store(volatile atomic<_Tp>* __o, _Tp __d)
840227825Stheraven{
841227825Stheraven    __o->store(__d);
842227825Stheraven}
843227825Stheraven
844227825Stheraventemplate <class _Tp>
845227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
846227825Stheravenvoid
847227825Stheravenatomic_store(atomic<_Tp>* __o, _Tp __d)
848227825Stheraven{
849227825Stheraven    __o->store(__d);
850227825Stheraven}
851227825Stheraven
852227825Stheraven// atomic_store_explicit
853227825Stheraven
854227825Stheraventemplate <class _Tp>
855227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
856227825Stheravenvoid
857227825Stheravenatomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m)
858227825Stheraven{
859227825Stheraven    __o->store(__d, __m);
860227825Stheraven}
861227825Stheraven
862227825Stheraventemplate <class _Tp>
863227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
864227825Stheravenvoid
865227825Stheravenatomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m)
866227825Stheraven{
867227825Stheraven    __o->store(__d, __m);
868227825Stheraven}
869227825Stheraven
870227825Stheraven// atomic_load
871227825Stheraven
872227825Stheraventemplate <class _Tp>
873227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
874227825Stheraven_Tp
875227825Stheravenatomic_load(const volatile atomic<_Tp>* __o)
876227825Stheraven{
877227825Stheraven    return __o->load();
878227825Stheraven}
879227825Stheraven
880227825Stheraventemplate <class _Tp>
881227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
882227825Stheraven_Tp
883227825Stheravenatomic_load(const atomic<_Tp>* __o)
884227825Stheraven{
885227825Stheraven    return __o->load();
886227825Stheraven}
887227825Stheraven
888227825Stheraven// atomic_load_explicit
889227825Stheraven
890227825Stheraventemplate <class _Tp>
891227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
892227825Stheraven_Tp
893227825Stheravenatomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m)
894227825Stheraven{
895227825Stheraven    return __o->load(__m);
896227825Stheraven}
897227825Stheraven
898227825Stheraventemplate <class _Tp>
899227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
900227825Stheraven_Tp
901227825Stheravenatomic_load_explicit(const atomic<_Tp>* __o, memory_order __m)
902227825Stheraven{
903227825Stheraven    return __o->load(__m);
904227825Stheraven}
905227825Stheraven
906227825Stheraven// atomic_exchange
907227825Stheraven
908227825Stheraventemplate <class _Tp>
909227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
910227825Stheraven_Tp
911227825Stheravenatomic_exchange(volatile atomic<_Tp>* __o, _Tp __d)
912227825Stheraven{
913227825Stheraven    return __o->exchange(__d);
914227825Stheraven}
915227825Stheraven
916227825Stheraventemplate <class _Tp>
917227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
918227825Stheraven_Tp
919227825Stheravenatomic_exchange(atomic<_Tp>* __o, _Tp __d)
920227825Stheraven{
921227825Stheraven    return __o->exchange(__d);
922227825Stheraven}
923227825Stheraven
924227825Stheraven// atomic_exchange_explicit
925227825Stheraven
926227825Stheraventemplate <class _Tp>
927227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
928227825Stheraven_Tp
929227825Stheravenatomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m)
930227825Stheraven{
931227825Stheraven    return __o->exchange(__d, __m);
932227825Stheraven}
933227825Stheraven
934227825Stheraventemplate <class _Tp>
935227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
936227825Stheraven_Tp
937227825Stheravenatomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m)
938227825Stheraven{
939227825Stheraven    return __o->exchange(__d, __m);
940227825Stheraven}
941227825Stheraven
942227825Stheraven// atomic_compare_exchange_weak
943227825Stheraven
944227825Stheraventemplate <class _Tp>
945227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
946227825Stheravenbool
947227825Stheravenatomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d)
948227825Stheraven{
949227825Stheraven    return __o->compare_exchange_weak(*__e, __d);
950227825Stheraven}
951227825Stheraven
952227825Stheraventemplate <class _Tp>
953227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
954227825Stheravenbool
955227825Stheravenatomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d)
956227825Stheraven{
957227825Stheraven    return __o->compare_exchange_weak(*__e, __d);
958227825Stheraven}
959227825Stheraven
960227825Stheraven// atomic_compare_exchange_strong
961227825Stheraven
962227825Stheraventemplate <class _Tp>
963227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
964227825Stheravenbool
965227825Stheravenatomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d)
966227825Stheraven{
967227825Stheraven    return __o->compare_exchange_strong(*__e, __d);
968227825Stheraven}
969227825Stheraven
970227825Stheraventemplate <class _Tp>
971227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
972227825Stheravenbool
973227825Stheravenatomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d)
974227825Stheraven{
975227825Stheraven    return __o->compare_exchange_strong(*__e, __d);
976227825Stheraven}
977227825Stheraven
978227825Stheraven// atomic_compare_exchange_weak_explicit
979227825Stheraven
980227825Stheraventemplate <class _Tp>
981227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
982227825Stheravenbool
983227825Stheravenatomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
984227825Stheraven                                      _Tp __d,
985227825Stheraven                                      memory_order __s, memory_order __f)
986227825Stheraven{
987227825Stheraven    return __o->compare_exchange_weak(*__e, __d, __s, __f);
988227825Stheraven}
989227825Stheraven
990227825Stheraventemplate <class _Tp>
991227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
992227825Stheravenbool
993227825Stheravenatomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
994227825Stheraven                                      memory_order __s, memory_order __f)
995227825Stheraven{
996227825Stheraven    return __o->compare_exchange_weak(*__e, __d, __s, __f);
997227825Stheraven}
998227825Stheraven
999227825Stheraven// atomic_compare_exchange_strong_explicit
1000227825Stheraven
1001227825Stheraventemplate <class _Tp>
1002227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1003227825Stheravenbool
1004227825Stheravenatomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1005227825Stheraven                                        _Tp* __e, _Tp __d,
1006227825Stheraven                                        memory_order __s, memory_order __f)
1007227825Stheraven{
1008227825Stheraven    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1009227825Stheraven}
1010227825Stheraven
1011227825Stheraventemplate <class _Tp>
1012227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1013227825Stheravenbool
1014227825Stheravenatomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1015227825Stheraven                                        _Tp __d,
1016227825Stheraven                                        memory_order __s, memory_order __f)
1017227825Stheraven{
1018227825Stheraven    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1019227825Stheraven}
1020227825Stheraven
1021227825Stheraven// atomic_fetch_add
1022227825Stheraven
1023227825Stheraventemplate <class _Tp>
1024227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1025227825Stheraventypename enable_if
1026227825Stheraven<
1027227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1028227825Stheraven    _Tp
1029227825Stheraven>::type
1030227825Stheravenatomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op)
1031227825Stheraven{
1032227825Stheraven    return __o->fetch_add(__op);
1033227825Stheraven}
1034227825Stheraven
1035227825Stheraventemplate <class _Tp>
1036227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1037227825Stheraventypename enable_if
1038227825Stheraven<
1039227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1040227825Stheraven    _Tp
1041227825Stheraven>::type
1042227825Stheravenatomic_fetch_add(atomic<_Tp>* __o, _Tp __op)
1043227825Stheraven{
1044227825Stheraven    return __o->fetch_add(__op);
1045227825Stheraven}
1046227825Stheraven
1047227825Stheraventemplate <class _Tp>
1048227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1049227825Stheraven_Tp*
1050227825Stheravenatomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op)
1051227825Stheraven{
1052227825Stheraven    return __o->fetch_add(__op);
1053227825Stheraven}
1054227825Stheraven
1055227825Stheraventemplate <class _Tp>
1056227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1057227825Stheraven_Tp*
1058227825Stheravenatomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op)
1059227825Stheraven{
1060227825Stheraven    return __o->fetch_add(__op);
1061227825Stheraven}
1062227825Stheraven
1063227825Stheraven// atomic_fetch_add_explicit
1064227825Stheraven
1065227825Stheraventemplate <class _Tp>
1066227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1067227825Stheraventypename enable_if
1068227825Stheraven<
1069227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1070227825Stheraven    _Tp
1071227825Stheraven>::type
1072227825Stheravenatomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1073227825Stheraven{
1074227825Stheraven    return __o->fetch_add(__op, __m);
1075227825Stheraven}
1076227825Stheraven
1077227825Stheraventemplate <class _Tp>
1078227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1079227825Stheraventypename enable_if
1080227825Stheraven<
1081227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1082227825Stheraven    _Tp
1083227825Stheraven>::type
1084227825Stheravenatomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1085227825Stheraven{
1086227825Stheraven    return __o->fetch_add(__op, __m);
1087227825Stheraven}
1088227825Stheraven
1089227825Stheraventemplate <class _Tp>
1090227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1091227825Stheraven_Tp*
1092227825Stheravenatomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1093227825Stheraven                          memory_order __m)
1094227825Stheraven{
1095227825Stheraven    return __o->fetch_add(__op, __m);
1096227825Stheraven}
1097227825Stheraven
1098227825Stheraventemplate <class _Tp>
1099227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1100227825Stheraven_Tp*
1101227825Stheravenatomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m)
1102227825Stheraven{
1103227825Stheraven    return __o->fetch_add(__op, __m);
1104227825Stheraven}
1105227825Stheraven
1106227825Stheraven// atomic_fetch_sub
1107227825Stheraven
1108227825Stheraventemplate <class _Tp>
1109227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1110227825Stheraventypename enable_if
1111227825Stheraven<
1112227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1113227825Stheraven    _Tp
1114227825Stheraven>::type
1115227825Stheravenatomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op)
1116227825Stheraven{
1117227825Stheraven    return __o->fetch_sub(__op);
1118227825Stheraven}
1119227825Stheraven
1120227825Stheraventemplate <class _Tp>
1121227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1122227825Stheraventypename enable_if
1123227825Stheraven<
1124227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1125227825Stheraven    _Tp
1126227825Stheraven>::type
1127227825Stheravenatomic_fetch_sub(atomic<_Tp>* __o, _Tp __op)
1128227825Stheraven{
1129227825Stheraven    return __o->fetch_sub(__op);
1130227825Stheraven}
1131227825Stheraven
1132227825Stheraventemplate <class _Tp>
1133227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1134227825Stheraven_Tp*
1135227825Stheravenatomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op)
1136227825Stheraven{
1137227825Stheraven    return __o->fetch_sub(__op);
1138227825Stheraven}
1139227825Stheraven
1140227825Stheraventemplate <class _Tp>
1141227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1142227825Stheraven_Tp*
1143227825Stheravenatomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op)
1144227825Stheraven{
1145227825Stheraven    return __o->fetch_sub(__op);
1146227825Stheraven}
1147227825Stheraven
1148227825Stheraven// atomic_fetch_sub_explicit
1149227825Stheraven
1150227825Stheraventemplate <class _Tp>
1151227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1152227825Stheraventypename enable_if
1153227825Stheraven<
1154227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1155227825Stheraven    _Tp
1156227825Stheraven>::type
1157227825Stheravenatomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1158227825Stheraven{
1159227825Stheraven    return __o->fetch_sub(__op, __m);
1160227825Stheraven}
1161227825Stheraven
1162227825Stheraventemplate <class _Tp>
1163227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1164227825Stheraventypename enable_if
1165227825Stheraven<
1166227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1167227825Stheraven    _Tp
1168227825Stheraven>::type
1169227825Stheravenatomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1170227825Stheraven{
1171227825Stheraven    return __o->fetch_sub(__op, __m);
1172227825Stheraven}
1173227825Stheraven
1174227825Stheraventemplate <class _Tp>
1175227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1176227825Stheraven_Tp*
1177227825Stheravenatomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1178227825Stheraven                          memory_order __m)
1179227825Stheraven{
1180227825Stheraven    return __o->fetch_sub(__op, __m);
1181227825Stheraven}
1182227825Stheraven
1183227825Stheraventemplate <class _Tp>
1184227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1185227825Stheraven_Tp*
1186227825Stheravenatomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m)
1187227825Stheraven{
1188227825Stheraven    return __o->fetch_sub(__op, __m);
1189227825Stheraven}
1190227825Stheraven
1191227825Stheraven// atomic_fetch_and
1192227825Stheraven
1193227825Stheraventemplate <class _Tp>
1194227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1195227825Stheraventypename enable_if
1196227825Stheraven<
1197227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1198227825Stheraven    _Tp
1199227825Stheraven>::type
1200227825Stheravenatomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op)
1201227825Stheraven{
1202227825Stheraven    return __o->fetch_and(__op);
1203227825Stheraven}
1204227825Stheraven
1205227825Stheraventemplate <class _Tp>
1206227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1207227825Stheraventypename enable_if
1208227825Stheraven<
1209227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1210227825Stheraven    _Tp
1211227825Stheraven>::type
1212227825Stheravenatomic_fetch_and(atomic<_Tp>* __o, _Tp __op)
1213227825Stheraven{
1214227825Stheraven    return __o->fetch_and(__op);
1215227825Stheraven}
1216227825Stheraven
1217227825Stheraven// atomic_fetch_and_explicit
1218227825Stheraven
1219227825Stheraventemplate <class _Tp>
1220227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1221227825Stheraventypename enable_if
1222227825Stheraven<
1223227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1224227825Stheraven    _Tp
1225227825Stheraven>::type
1226227825Stheravenatomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1227227825Stheraven{
1228227825Stheraven    return __o->fetch_and(__op, __m);
1229227825Stheraven}
1230227825Stheraven
1231227825Stheraventemplate <class _Tp>
1232227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1233227825Stheraventypename enable_if
1234227825Stheraven<
1235227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1236227825Stheraven    _Tp
1237227825Stheraven>::type
1238227825Stheravenatomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1239227825Stheraven{
1240227825Stheraven    return __o->fetch_and(__op, __m);
1241227825Stheraven}
1242227825Stheraven
1243227825Stheraven// atomic_fetch_or
1244227825Stheraven
1245227825Stheraventemplate <class _Tp>
1246227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1247227825Stheraventypename enable_if
1248227825Stheraven<
1249227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1250227825Stheraven    _Tp
1251227825Stheraven>::type
1252227825Stheravenatomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op)
1253227825Stheraven{
1254227825Stheraven    return __o->fetch_or(__op);
1255227825Stheraven}
1256227825Stheraven
1257227825Stheraventemplate <class _Tp>
1258227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1259227825Stheraventypename enable_if
1260227825Stheraven<
1261227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1262227825Stheraven    _Tp
1263227825Stheraven>::type
1264227825Stheravenatomic_fetch_or(atomic<_Tp>* __o, _Tp __op)
1265227825Stheraven{
1266227825Stheraven    return __o->fetch_or(__op);
1267227825Stheraven}
1268227825Stheraven
1269227825Stheraven// atomic_fetch_or_explicit
1270227825Stheraven
1271227825Stheraventemplate <class _Tp>
1272227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1273227825Stheraventypename enable_if
1274227825Stheraven<
1275227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1276227825Stheraven    _Tp
1277227825Stheraven>::type
1278227825Stheravenatomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1279227825Stheraven{
1280227825Stheraven    return __o->fetch_or(__op, __m);
1281227825Stheraven}
1282227825Stheraven
1283227825Stheraventemplate <class _Tp>
1284227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1285227825Stheraventypename enable_if
1286227825Stheraven<
1287227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1288227825Stheraven    _Tp
1289227825Stheraven>::type
1290227825Stheravenatomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1291227825Stheraven{
1292227825Stheraven    return __o->fetch_or(__op, __m);
1293227825Stheraven}
1294227825Stheraven
1295227825Stheraven// atomic_fetch_xor
1296227825Stheraven
1297227825Stheraventemplate <class _Tp>
1298227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1299227825Stheraventypename enable_if
1300227825Stheraven<
1301227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1302227825Stheraven    _Tp
1303227825Stheraven>::type
1304227825Stheravenatomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op)
1305227825Stheraven{
1306227825Stheraven    return __o->fetch_xor(__op);
1307227825Stheraven}
1308227825Stheraven
1309227825Stheraventemplate <class _Tp>
1310227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1311227825Stheraventypename enable_if
1312227825Stheraven<
1313227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1314227825Stheraven    _Tp
1315227825Stheraven>::type
1316227825Stheravenatomic_fetch_xor(atomic<_Tp>* __o, _Tp __op)
1317227825Stheraven{
1318227825Stheraven    return __o->fetch_xor(__op);
1319227825Stheraven}
1320227825Stheraven
1321227825Stheraven// atomic_fetch_xor_explicit
1322227825Stheraven
1323227825Stheraventemplate <class _Tp>
1324227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1325227825Stheraventypename enable_if
1326227825Stheraven<
1327227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1328227825Stheraven    _Tp
1329227825Stheraven>::type
1330227825Stheravenatomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1331227825Stheraven{
1332227825Stheraven    return __o->fetch_xor(__op, __m);
1333227825Stheraven}
1334227825Stheraven
1335227825Stheraventemplate <class _Tp>
1336227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1337227825Stheraventypename enable_if
1338227825Stheraven<
1339227825Stheraven    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1340227825Stheraven    _Tp
1341227825Stheraven>::type
1342227825Stheravenatomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1343227825Stheraven{
1344227825Stheraven    return __o->fetch_xor(__op, __m);
1345227825Stheraven}
1346227825Stheraven
1347227825Stheraven// flag type and operations
1348227825Stheraven
1349227825Stheraventypedef struct atomic_flag
1350227825Stheraven{
1351232924Stheraven    _Atomic(bool) __a_;
1352227825Stheraven
1353227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1354227825Stheraven    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile
1355227825Stheraven        {return __atomic_exchange(&__a_, true, __m);}
1356227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1357227825Stheraven    bool test_and_set(memory_order __m = memory_order_seq_cst)
1358227825Stheraven        {return __atomic_exchange(&__a_, true, __m);}
1359227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1360227825Stheraven    void clear(memory_order __m = memory_order_seq_cst) volatile
1361227825Stheraven        {__atomic_store(&__a_, false, __m);}
1362227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1363227825Stheraven    void clear(memory_order __m = memory_order_seq_cst)
1364227825Stheraven        {__atomic_store(&__a_, false, __m);}
1365227825Stheraven
1366227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1367227825Stheraven    atomic_flag() {} // = default;
1368227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1369232924Stheraven    atomic_flag(bool __b) { __atomic_store(&__a_, __b, memory_order_seq_cst); }
1370227825Stheraven
1371227825Stheraven#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1372227825Stheraven    atomic_flag(const atomic_flag&) = delete;
1373227825Stheraven    atomic_flag& operator=(const atomic_flag&) = delete;
1374227825Stheraven    atomic_flag& operator=(const atomic_flag&) volatile = delete;
1375227825Stheraven#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1376227825Stheravenprivate:
1377227825Stheraven    atomic_flag(const atomic_flag&);
1378227825Stheraven    atomic_flag& operator=(const atomic_flag&);
1379227825Stheraven    atomic_flag& operator=(const atomic_flag&) volatile;
1380227825Stheraven#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1381227825Stheraven} atomic_flag;
1382227825Stheraven
1383227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1384227825Stheravenbool
1385227825Stheravenatomic_flag_test_and_set(volatile atomic_flag* __o)
1386227825Stheraven{
1387227825Stheraven    return __o->test_and_set();
1388227825Stheraven}
1389227825Stheraven
1390227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1391227825Stheravenbool
1392227825Stheravenatomic_flag_test_and_set(atomic_flag* __o)
1393227825Stheraven{
1394227825Stheraven    return __o->test_and_set();
1395227825Stheraven}
1396227825Stheraven
1397227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1398227825Stheravenbool
1399227825Stheravenatomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m)
1400227825Stheraven{
1401227825Stheraven    return __o->test_and_set(__m);
1402227825Stheraven}
1403227825Stheraven
1404227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1405227825Stheravenbool
1406227825Stheravenatomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m)
1407227825Stheraven{
1408227825Stheraven    return __o->test_and_set(__m);
1409227825Stheraven}
1410227825Stheraven
1411227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1412227825Stheravenvoid
1413227825Stheravenatomic_flag_clear(volatile atomic_flag* __o)
1414227825Stheraven{
1415227825Stheraven    __o->clear();
1416227825Stheraven}
1417227825Stheraven
1418227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1419227825Stheravenvoid
1420227825Stheravenatomic_flag_clear(atomic_flag* __o)
1421227825Stheraven{
1422227825Stheraven    __o->clear();
1423227825Stheraven}
1424227825Stheraven
1425227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1426227825Stheravenvoid
1427227825Stheravenatomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m)
1428227825Stheraven{
1429227825Stheraven    __o->clear(__m);
1430227825Stheraven}
1431227825Stheraven
1432227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1433227825Stheravenvoid
1434227825Stheravenatomic_flag_clear_explicit(atomic_flag* __o, memory_order __m)
1435227825Stheraven{
1436227825Stheraven    __o->clear(__m);
1437227825Stheraven}
1438227825Stheraven
1439227825Stheraven// fences
1440227825Stheraven
1441227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1442227825Stheravenvoid
1443227825Stheravenatomic_thread_fence(memory_order __m)
1444227825Stheraven{
1445227825Stheraven    __atomic_thread_fence(__m);
1446227825Stheraven}
1447227825Stheraven
1448227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1449227825Stheravenvoid
1450227825Stheravenatomic_signal_fence(memory_order __m)
1451227825Stheraven{
1452227825Stheraven    __atomic_signal_fence(__m);
1453227825Stheraven}
1454227825Stheraven
1455227825Stheraven// Atomics for standard typedef types
1456227825Stheraven
1457227825Stheraventypedef atomic<char>               atomic_char;
1458227825Stheraventypedef atomic<signed char>        atomic_schar;
1459227825Stheraventypedef atomic<unsigned char>      atomic_uchar;
1460227825Stheraventypedef atomic<short>              atomic_short;
1461227825Stheraventypedef atomic<unsigned short>     atomic_ushort;
1462227825Stheraventypedef atomic<int>                atomic_int;
1463227825Stheraventypedef atomic<unsigned int>       atomic_uint;
1464227825Stheraventypedef atomic<long>               atomic_long;
1465227825Stheraventypedef atomic<unsigned long>      atomic_ulong;
1466227825Stheraventypedef atomic<long long>          atomic_llong;
1467227825Stheraventypedef atomic<unsigned long long> atomic_ullong;
1468227825Stheraventypedef atomic<char16_t>           atomic_char16_t;
1469227825Stheraventypedef atomic<char32_t>           atomic_char32_t;
1470227825Stheraventypedef atomic<wchar_t>            atomic_wchar_t;
1471227825Stheraven
1472227825Stheraventypedef atomic<int_least8_t>   atomic_int_least8_t;
1473227825Stheraventypedef atomic<uint_least8_t>  atomic_uint_least8_t;
1474227825Stheraventypedef atomic<int_least16_t>  atomic_int_least16_t;
1475227825Stheraventypedef atomic<uint_least16_t> atomic_uint_least16_t;
1476227825Stheraventypedef atomic<int_least32_t>  atomic_int_least32_t;
1477227825Stheraventypedef atomic<uint_least32_t> atomic_uint_least32_t;
1478227825Stheraventypedef atomic<int_least64_t>  atomic_int_least64_t;
1479227825Stheraventypedef atomic<uint_least64_t> atomic_uint_least64_t;
1480227825Stheraven
1481227825Stheraventypedef atomic<int_fast8_t>   atomic_int_fast8_t;
1482227825Stheraventypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
1483227825Stheraventypedef atomic<int_fast16_t>  atomic_int_fast16_t;
1484227825Stheraventypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1485227825Stheraventypedef atomic<int_fast32_t>  atomic_int_fast32_t;
1486227825Stheraventypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1487227825Stheraventypedef atomic<int_fast64_t>  atomic_int_fast64_t;
1488227825Stheraventypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1489227825Stheraven
1490227825Stheraventypedef atomic<intptr_t>  atomic_intptr_t;
1491227825Stheraventypedef atomic<uintptr_t> atomic_uintptr_t;
1492227825Stheraventypedef atomic<size_t>    atomic_size_t;
1493227825Stheraventypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1494227825Stheraventypedef atomic<intmax_t>  atomic_intmax_t;
1495227825Stheraventypedef atomic<uintmax_t> atomic_uintmax_t;
1496227825Stheraven
1497227825Stheraven#define ATOMIC_FLAG_INIT {false}
1498227825Stheraven#define ATOMIC_VAR_INIT(__v) {__v}
1499227825Stheraven
1500227825Stheraven// lock-free property
1501227825Stheraven
1502227825Stheraven#define ATOMIC_CHAR_LOCK_FREE 0
1503227825Stheraven#define ATOMIC_CHAR16_T_LOCK_FREE 0
1504227825Stheraven#define ATOMIC_CHAR32_T_LOCK_FREE 0
1505227825Stheraven#define ATOMIC_WCHAR_T_LOCK_FREE 0
1506227825Stheraven#define ATOMIC_SHORT_LOCK_FREE 0
1507227825Stheraven#define ATOMIC_INT_LOCK_FREE 0
1508227825Stheraven#define ATOMIC_LONG_LOCK_FREE 0
1509227825Stheraven#define ATOMIC_LLONG_LOCK_FREE 0
1510227825Stheraven
1511227825Stheraven#endif  //  !__has_feature(cxx_atomic)
1512227825Stheraven
1513227825Stheraven_LIBCPP_END_NAMESPACE_STD
1514227825Stheraven
1515227825Stheraven#endif  // _LIBCPP_ATOMIC
1516