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