xref: /freebsd-12.1/contrib/libc++/include/atomic (revision b5893f02)
17a984708SDavid Chisnall// -*- C++ -*-
27a984708SDavid Chisnall//===--------------------------- atomic -----------------------------------===//
37a984708SDavid Chisnall//
47a984708SDavid Chisnall//                     The LLVM Compiler Infrastructure
57a984708SDavid Chisnall//
67a984708SDavid Chisnall// This file is distributed under the University of Illinois Open Source
77a984708SDavid Chisnall// License. See LICENSE.TXT for details.
87a984708SDavid Chisnall//
97a984708SDavid Chisnall//===----------------------------------------------------------------------===//
107a984708SDavid Chisnall
117a984708SDavid Chisnall#ifndef _LIBCPP_ATOMIC
127a984708SDavid Chisnall#define _LIBCPP_ATOMIC
137a984708SDavid Chisnall
147a984708SDavid Chisnall/*
157a984708SDavid Chisnall    atomic synopsis
167a984708SDavid Chisnall
177a984708SDavid Chisnallnamespace std
187a984708SDavid Chisnall{
197a984708SDavid Chisnall
207c82a1ecSDimitry Andric// feature test macro
217c82a1ecSDimitry Andric
227c82a1ecSDimitry Andric#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10
237c82a1ecSDimitry Andric
247a984708SDavid Chisnall// order and consistency
257a984708SDavid Chisnall
267a984708SDavid Chisnalltypedef enum memory_order
277a984708SDavid Chisnall{
287a984708SDavid Chisnall    memory_order_relaxed,
297a984708SDavid Chisnall    memory_order_consume,  // load-consume
307a984708SDavid Chisnall    memory_order_acquire,  // load-acquire
317a984708SDavid Chisnall    memory_order_release,  // store-release
327a984708SDavid Chisnall    memory_order_acq_rel,  // store-release load-acquire
337a984708SDavid Chisnall    memory_order_seq_cst   // store-release load-acquire
347a984708SDavid Chisnall} memory_order;
357a984708SDavid Chisnall
36b03f91a8SDavid Chisnalltemplate <class T> T kill_dependency(T y) noexcept;
377a984708SDavid Chisnall
387a984708SDavid Chisnall// lock-free property
397a984708SDavid Chisnall
40cfdf2879SDavid Chisnall#define ATOMIC_BOOL_LOCK_FREE unspecified
417a984708SDavid Chisnall#define ATOMIC_CHAR_LOCK_FREE unspecified
427a984708SDavid Chisnall#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
437a984708SDavid Chisnall#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
447a984708SDavid Chisnall#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
457a984708SDavid Chisnall#define ATOMIC_SHORT_LOCK_FREE unspecified
467a984708SDavid Chisnall#define ATOMIC_INT_LOCK_FREE unspecified
477a984708SDavid Chisnall#define ATOMIC_LONG_LOCK_FREE unspecified
487a984708SDavid Chisnall#define ATOMIC_LLONG_LOCK_FREE unspecified
49cfdf2879SDavid Chisnall#define ATOMIC_POINTER_LOCK_FREE unspecified
507a984708SDavid Chisnall
517a984708SDavid Chisnall// flag type and operations
527a984708SDavid Chisnall
537a984708SDavid Chisnalltypedef struct atomic_flag
547a984708SDavid Chisnall{
55b03f91a8SDavid Chisnall    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
56b03f91a8SDavid Chisnall    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
57b03f91a8SDavid Chisnall    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
58b03f91a8SDavid Chisnall    void clear(memory_order m = memory_order_seq_cst) noexcept;
59b03f91a8SDavid Chisnall    atomic_flag()  noexcept = default;
607a984708SDavid Chisnall    atomic_flag(const atomic_flag&) = delete;
617a984708SDavid Chisnall    atomic_flag& operator=(const atomic_flag&) = delete;
627a984708SDavid Chisnall    atomic_flag& operator=(const atomic_flag&) volatile = delete;
637a984708SDavid Chisnall} atomic_flag;
647a984708SDavid Chisnall
657a984708SDavid Chisnallbool
66b03f91a8SDavid Chisnall    atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
677a984708SDavid Chisnall
687a984708SDavid Chisnallbool
69b03f91a8SDavid Chisnall    atomic_flag_test_and_set(atomic_flag* obj) noexcept;
707a984708SDavid Chisnall
717a984708SDavid Chisnallbool
727a984708SDavid Chisnall    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
73b03f91a8SDavid Chisnall                                      memory_order m) noexcept;
747a984708SDavid Chisnall
757a984708SDavid Chisnallbool
76b03f91a8SDavid Chisnall    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
777a984708SDavid Chisnall
787a984708SDavid Chisnallvoid
79b03f91a8SDavid Chisnall    atomic_flag_clear(volatile atomic_flag* obj) noexcept;
807a984708SDavid Chisnall
817a984708SDavid Chisnallvoid
82b03f91a8SDavid Chisnall    atomic_flag_clear(atomic_flag* obj) noexcept;
837a984708SDavid Chisnall
847a984708SDavid Chisnallvoid
85b03f91a8SDavid Chisnall    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
867a984708SDavid Chisnall
877a984708SDavid Chisnallvoid
88b03f91a8SDavid Chisnall    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
897a984708SDavid Chisnall
907a984708SDavid Chisnall#define ATOMIC_FLAG_INIT see below
917a984708SDavid Chisnall#define ATOMIC_VAR_INIT(value) see below
927a984708SDavid Chisnall
937a984708SDavid Chisnalltemplate <class T>
947a984708SDavid Chisnallstruct atomic
957a984708SDavid Chisnall{
967c82a1ecSDimitry Andric    static constexpr bool is_always_lock_free;
97b03f91a8SDavid Chisnall    bool is_lock_free() const volatile noexcept;
98b03f91a8SDavid Chisnall    bool is_lock_free() const noexcept;
99b03f91a8SDavid Chisnall    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
100b03f91a8SDavid Chisnall    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
101b03f91a8SDavid Chisnall    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
102b03f91a8SDavid Chisnall    T load(memory_order m = memory_order_seq_cst) const noexcept;
103b03f91a8SDavid Chisnall    operator T() const volatile noexcept;
104b03f91a8SDavid Chisnall    operator T() const noexcept;
105b03f91a8SDavid Chisnall    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
106b03f91a8SDavid Chisnall    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
1077a984708SDavid Chisnall    bool compare_exchange_weak(T& expc, T desr,
108b03f91a8SDavid Chisnall                               memory_order s, memory_order f) volatile noexcept;
109b03f91a8SDavid Chisnall    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
1107a984708SDavid Chisnall    bool compare_exchange_strong(T& expc, T desr,
111b03f91a8SDavid Chisnall                                 memory_order s, memory_order f) volatile noexcept;
1127a984708SDavid Chisnall    bool compare_exchange_strong(T& expc, T desr,
113b03f91a8SDavid Chisnall                                 memory_order s, memory_order f) noexcept;
1147a984708SDavid Chisnall    bool compare_exchange_weak(T& expc, T desr,
115b03f91a8SDavid Chisnall                               memory_order m = memory_order_seq_cst) volatile noexcept;
1167a984708SDavid Chisnall    bool compare_exchange_weak(T& expc, T desr,
117b03f91a8SDavid Chisnall                               memory_order m = memory_order_seq_cst) noexcept;
1187a984708SDavid Chisnall    bool compare_exchange_strong(T& expc, T desr,
119b03f91a8SDavid Chisnall                                memory_order m = memory_order_seq_cst) volatile noexcept;
1207a984708SDavid Chisnall    bool compare_exchange_strong(T& expc, T desr,
121b03f91a8SDavid Chisnall                                 memory_order m = memory_order_seq_cst) noexcept;
1227a984708SDavid Chisnall
123b03f91a8SDavid Chisnall    atomic() noexcept = default;
124b03f91a8SDavid Chisnall    constexpr atomic(T desr) noexcept;
1257a984708SDavid Chisnall    atomic(const atomic&) = delete;
1267a984708SDavid Chisnall    atomic& operator=(const atomic&) = delete;
1277a984708SDavid Chisnall    atomic& operator=(const atomic&) volatile = delete;
128b03f91a8SDavid Chisnall    T operator=(T) volatile noexcept;
129b03f91a8SDavid Chisnall    T operator=(T) noexcept;
1307a984708SDavid Chisnall};
1317a984708SDavid Chisnall
1327a984708SDavid Chisnalltemplate <>
1337a984708SDavid Chisnallstruct atomic<integral>
1347a984708SDavid Chisnall{
1357c82a1ecSDimitry Andric    static constexpr bool is_always_lock_free;
136b03f91a8SDavid Chisnall    bool is_lock_free() const volatile noexcept;
137b03f91a8SDavid Chisnall    bool is_lock_free() const noexcept;
138b03f91a8SDavid Chisnall    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
139b03f91a8SDavid Chisnall    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
140b03f91a8SDavid Chisnall    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
141b03f91a8SDavid Chisnall    integral load(memory_order m = memory_order_seq_cst) const noexcept;
142b03f91a8SDavid Chisnall    operator integral() const volatile noexcept;
143b03f91a8SDavid Chisnall    operator integral() const noexcept;
1447a984708SDavid Chisnall    integral exchange(integral desr,
145b03f91a8SDavid Chisnall                      memory_order m = memory_order_seq_cst) volatile noexcept;
146b03f91a8SDavid Chisnall    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1477a984708SDavid Chisnall    bool compare_exchange_weak(integral& expc, integral desr,
148b03f91a8SDavid Chisnall                               memory_order s, memory_order f) volatile noexcept;
1497a984708SDavid Chisnall    bool compare_exchange_weak(integral& expc, integral desr,
150b03f91a8SDavid Chisnall                               memory_order s, memory_order f) noexcept;
1517a984708SDavid Chisnall    bool compare_exchange_strong(integral& expc, integral desr,
152b03f91a8SDavid Chisnall                                 memory_order s, memory_order f) volatile noexcept;
1537a984708SDavid Chisnall    bool compare_exchange_strong(integral& expc, integral desr,
154b03f91a8SDavid Chisnall                                 memory_order s, memory_order f) noexcept;
1557a984708SDavid Chisnall    bool compare_exchange_weak(integral& expc, integral desr,
156b03f91a8SDavid Chisnall                               memory_order m = memory_order_seq_cst) volatile noexcept;
1577a984708SDavid Chisnall    bool compare_exchange_weak(integral& expc, integral desr,
158b03f91a8SDavid Chisnall                               memory_order m = memory_order_seq_cst) noexcept;
1597a984708SDavid Chisnall    bool compare_exchange_strong(integral& expc, integral desr,
160b03f91a8SDavid Chisnall                                memory_order m = memory_order_seq_cst) volatile noexcept;
1617a984708SDavid Chisnall    bool compare_exchange_strong(integral& expc, integral desr,
162b03f91a8SDavid Chisnall                                 memory_order m = memory_order_seq_cst) noexcept;
1637a984708SDavid Chisnall
1647a984708SDavid Chisnall    integral
165b03f91a8SDavid Chisnall        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
166b03f91a8SDavid Chisnall    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
1677a984708SDavid Chisnall    integral
168b03f91a8SDavid Chisnall        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
169b03f91a8SDavid Chisnall    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
1707a984708SDavid Chisnall    integral
171b03f91a8SDavid Chisnall        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
172b03f91a8SDavid Chisnall    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
1737a984708SDavid Chisnall    integral
174b03f91a8SDavid Chisnall        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
175b03f91a8SDavid Chisnall    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
1767a984708SDavid Chisnall    integral
177b03f91a8SDavid Chisnall        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
178b03f91a8SDavid Chisnall    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
1797a984708SDavid Chisnall
180b03f91a8SDavid Chisnall    atomic() noexcept = default;
181b03f91a8SDavid Chisnall    constexpr atomic(integral desr) noexcept;
1827a984708SDavid Chisnall    atomic(const atomic&) = delete;
1837a984708SDavid Chisnall    atomic& operator=(const atomic&) = delete;
1847a984708SDavid Chisnall    atomic& operator=(const atomic&) volatile = delete;
185b03f91a8SDavid Chisnall    integral operator=(integral desr) volatile noexcept;
186b03f91a8SDavid Chisnall    integral operator=(integral desr) noexcept;
1877a984708SDavid Chisnall
188b03f91a8SDavid Chisnall    integral operator++(int) volatile noexcept;
189b03f91a8SDavid Chisnall    integral operator++(int) noexcept;
190b03f91a8SDavid Chisnall    integral operator--(int) volatile noexcept;
191b03f91a8SDavid Chisnall    integral operator--(int) noexcept;
192b03f91a8SDavid Chisnall    integral operator++() volatile noexcept;
193b03f91a8SDavid Chisnall    integral operator++() noexcept;
194b03f91a8SDavid Chisnall    integral operator--() volatile noexcept;
195b03f91a8SDavid Chisnall    integral operator--() noexcept;
196b03f91a8SDavid Chisnall    integral operator+=(integral op) volatile noexcept;
197b03f91a8SDavid Chisnall    integral operator+=(integral op) noexcept;
198b03f91a8SDavid Chisnall    integral operator-=(integral op) volatile noexcept;
199b03f91a8SDavid Chisnall    integral operator-=(integral op) noexcept;
200b03f91a8SDavid Chisnall    integral operator&=(integral op) volatile noexcept;
201b03f91a8SDavid Chisnall    integral operator&=(integral op) noexcept;
202b03f91a8SDavid Chisnall    integral operator|=(integral op) volatile noexcept;
203b03f91a8SDavid Chisnall    integral operator|=(integral op) noexcept;
204b03f91a8SDavid Chisnall    integral operator^=(integral op) volatile noexcept;
205b03f91a8SDavid Chisnall    integral operator^=(integral op) noexcept;
2067a984708SDavid Chisnall};
2077a984708SDavid Chisnall
2087a984708SDavid Chisnalltemplate <class T>
2097a984708SDavid Chisnallstruct atomic<T*>
2107a984708SDavid Chisnall{
2117c82a1ecSDimitry Andric    static constexpr bool is_always_lock_free;
212b03f91a8SDavid Chisnall    bool is_lock_free() const volatile noexcept;
213b03f91a8SDavid Chisnall    bool is_lock_free() const noexcept;
214b03f91a8SDavid Chisnall    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
215b03f91a8SDavid Chisnall    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
216b03f91a8SDavid Chisnall    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
217b03f91a8SDavid Chisnall    T* load(memory_order m = memory_order_seq_cst) const noexcept;
218b03f91a8SDavid Chisnall    operator T*() const volatile noexcept;
219b03f91a8SDavid Chisnall    operator T*() const noexcept;
220b03f91a8SDavid Chisnall    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
221b03f91a8SDavid Chisnall    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2227a984708SDavid Chisnall    bool compare_exchange_weak(T*& expc, T* desr,
223b03f91a8SDavid Chisnall                               memory_order s, memory_order f) volatile noexcept;
2247a984708SDavid Chisnall    bool compare_exchange_weak(T*& expc, T* desr,
225b03f91a8SDavid Chisnall                               memory_order s, memory_order f) noexcept;
2267a984708SDavid Chisnall    bool compare_exchange_strong(T*& expc, T* desr,
227b03f91a8SDavid Chisnall                                 memory_order s, memory_order f) volatile noexcept;
2287a984708SDavid Chisnall    bool compare_exchange_strong(T*& expc, T* desr,
229b03f91a8SDavid Chisnall                                 memory_order s, memory_order f) noexcept;
2307a984708SDavid Chisnall    bool compare_exchange_weak(T*& expc, T* desr,
231b03f91a8SDavid Chisnall                               memory_order m = memory_order_seq_cst) volatile noexcept;
2327a984708SDavid Chisnall    bool compare_exchange_weak(T*& expc, T* desr,
233b03f91a8SDavid Chisnall                               memory_order m = memory_order_seq_cst) noexcept;
2347a984708SDavid Chisnall    bool compare_exchange_strong(T*& expc, T* desr,
235b03f91a8SDavid Chisnall                                memory_order m = memory_order_seq_cst) volatile noexcept;
2367a984708SDavid Chisnall    bool compare_exchange_strong(T*& expc, T* desr,
237b03f91a8SDavid Chisnall                                 memory_order m = memory_order_seq_cst) noexcept;
238b03f91a8SDavid Chisnall    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
239b03f91a8SDavid Chisnall    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
240b03f91a8SDavid Chisnall    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
241b03f91a8SDavid Chisnall    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2427a984708SDavid Chisnall
243b03f91a8SDavid Chisnall    atomic() noexcept = default;
244b03f91a8SDavid Chisnall    constexpr atomic(T* desr) noexcept;
2457a984708SDavid Chisnall    atomic(const atomic&) = delete;
2467a984708SDavid Chisnall    atomic& operator=(const atomic&) = delete;
2477a984708SDavid Chisnall    atomic& operator=(const atomic&) volatile = delete;
2487a984708SDavid Chisnall
249b03f91a8SDavid Chisnall    T* operator=(T*) volatile noexcept;
250b03f91a8SDavid Chisnall    T* operator=(T*) noexcept;
251b03f91a8SDavid Chisnall    T* operator++(int) volatile noexcept;
252b03f91a8SDavid Chisnall    T* operator++(int) noexcept;
253b03f91a8SDavid Chisnall    T* operator--(int) volatile noexcept;
254b03f91a8SDavid Chisnall    T* operator--(int) noexcept;
255b03f91a8SDavid Chisnall    T* operator++() volatile noexcept;
256b03f91a8SDavid Chisnall    T* operator++() noexcept;
257b03f91a8SDavid Chisnall    T* operator--() volatile noexcept;
258b03f91a8SDavid Chisnall    T* operator--() noexcept;
259b03f91a8SDavid Chisnall    T* operator+=(ptrdiff_t op) volatile noexcept;
260b03f91a8SDavid Chisnall    T* operator+=(ptrdiff_t op) noexcept;
261b03f91a8SDavid Chisnall    T* operator-=(ptrdiff_t op) volatile noexcept;
262b03f91a8SDavid Chisnall    T* operator-=(ptrdiff_t op) noexcept;
2637a984708SDavid Chisnall};
2647a984708SDavid Chisnall
2657a984708SDavid Chisnall
2667a984708SDavid Chisnalltemplate <class T>
2677a984708SDavid Chisnall    bool
268b03f91a8SDavid Chisnall    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
2697a984708SDavid Chisnall
2707a984708SDavid Chisnalltemplate <class T>
2717a984708SDavid Chisnall    bool
272b03f91a8SDavid Chisnall    atomic_is_lock_free(const atomic<T>* obj) noexcept;
2737a984708SDavid Chisnall
2747a984708SDavid Chisnalltemplate <class T>
2757a984708SDavid Chisnall    void
276b03f91a8SDavid Chisnall    atomic_init(volatile atomic<T>* obj, T desr) noexcept;
2777a984708SDavid Chisnall
2787a984708SDavid Chisnalltemplate <class T>
2797a984708SDavid Chisnall    void
280b03f91a8SDavid Chisnall    atomic_init(atomic<T>* obj, T desr) noexcept;
2817a984708SDavid Chisnall
2827a984708SDavid Chisnalltemplate <class T>
2837a984708SDavid Chisnall    void
284b03f91a8SDavid Chisnall    atomic_store(volatile atomic<T>* obj, T desr) noexcept;
2857a984708SDavid Chisnall
2867a984708SDavid Chisnalltemplate <class T>
2877a984708SDavid Chisnall    void
288b03f91a8SDavid Chisnall    atomic_store(atomic<T>* obj, T desr) noexcept;
2897a984708SDavid Chisnall
2907a984708SDavid Chisnalltemplate <class T>
2917a984708SDavid Chisnall    void
292b03f91a8SDavid Chisnall    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
2937a984708SDavid Chisnall
2947a984708SDavid Chisnalltemplate <class T>
2957a984708SDavid Chisnall    void
296b03f91a8SDavid Chisnall    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
2977a984708SDavid Chisnall
2987a984708SDavid Chisnalltemplate <class T>
2997a984708SDavid Chisnall    T
300b03f91a8SDavid Chisnall    atomic_load(const volatile atomic<T>* obj) noexcept;
3017a984708SDavid Chisnall
3027a984708SDavid Chisnalltemplate <class T>
3037a984708SDavid Chisnall    T
304b03f91a8SDavid Chisnall    atomic_load(const atomic<T>* obj) noexcept;
3057a984708SDavid Chisnall
3067a984708SDavid Chisnalltemplate <class T>
3077a984708SDavid Chisnall    T
308b03f91a8SDavid Chisnall    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
3097a984708SDavid Chisnall
3107a984708SDavid Chisnalltemplate <class T>
3117a984708SDavid Chisnall    T
312b03f91a8SDavid Chisnall    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
3137a984708SDavid Chisnall
3147a984708SDavid Chisnalltemplate <class T>
3157a984708SDavid Chisnall    T
316b03f91a8SDavid Chisnall    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
3177a984708SDavid Chisnall
3187a984708SDavid Chisnalltemplate <class T>
3197a984708SDavid Chisnall    T
320b03f91a8SDavid Chisnall    atomic_exchange(atomic<T>* obj, T desr) noexcept;
3217a984708SDavid Chisnall
3227a984708SDavid Chisnalltemplate <class T>
3237a984708SDavid Chisnall    T
324b03f91a8SDavid Chisnall    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
3257a984708SDavid Chisnall
3267a984708SDavid Chisnalltemplate <class T>
3277a984708SDavid Chisnall    T
328b03f91a8SDavid Chisnall    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
3297a984708SDavid Chisnall
3307a984708SDavid Chisnalltemplate <class T>
3317a984708SDavid Chisnall    bool
332b03f91a8SDavid Chisnall    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
3337a984708SDavid Chisnall
3347a984708SDavid Chisnalltemplate <class T>
3357a984708SDavid Chisnall    bool
336b03f91a8SDavid Chisnall    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
3377a984708SDavid Chisnall
3387a984708SDavid Chisnalltemplate <class T>
3397a984708SDavid Chisnall    bool
340b03f91a8SDavid Chisnall    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
3417a984708SDavid Chisnall
3427a984708SDavid Chisnalltemplate <class T>
3437a984708SDavid Chisnall    bool
344b03f91a8SDavid Chisnall    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
3457a984708SDavid Chisnall
3467a984708SDavid Chisnalltemplate <class T>
3477a984708SDavid Chisnall    bool
3487a984708SDavid Chisnall    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
3497a984708SDavid Chisnall                                          T desr,
350b03f91a8SDavid Chisnall                                          memory_order s, memory_order f) noexcept;
3517a984708SDavid Chisnall
3527a984708SDavid Chisnalltemplate <class T>
3537a984708SDavid Chisnall    bool
3547a984708SDavid Chisnall    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
355b03f91a8SDavid Chisnall                                          memory_order s, memory_order f) noexcept;
3567a984708SDavid Chisnall
3577a984708SDavid Chisnalltemplate <class T>
3587a984708SDavid Chisnall    bool
3597a984708SDavid Chisnall    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
3607a984708SDavid Chisnall                                            T* expc, T desr,
361b03f91a8SDavid Chisnall                                            memory_order s, memory_order f) noexcept;
3627a984708SDavid Chisnall
3637a984708SDavid Chisnalltemplate <class T>
3647a984708SDavid Chisnall    bool
3657a984708SDavid Chisnall    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
3667a984708SDavid Chisnall                                            T desr,
367b03f91a8SDavid Chisnall                                            memory_order s, memory_order f) noexcept;
3687a984708SDavid Chisnall
3697a984708SDavid Chisnalltemplate <class Integral>
3707a984708SDavid Chisnall    Integral
371b03f91a8SDavid Chisnall    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
3727a984708SDavid Chisnall
3737a984708SDavid Chisnalltemplate <class Integral>
3747a984708SDavid Chisnall    Integral
375b03f91a8SDavid Chisnall    atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
3767a984708SDavid Chisnall
3777a984708SDavid Chisnalltemplate <class Integral>
3787a984708SDavid Chisnall    Integral
3797a984708SDavid Chisnall    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
380b03f91a8SDavid Chisnall                              memory_order m) noexcept;
3817a984708SDavid Chisnalltemplate <class Integral>
3827a984708SDavid Chisnall    Integral
3837a984708SDavid Chisnall    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
384b03f91a8SDavid Chisnall                              memory_order m) noexcept;
3857a984708SDavid Chisnalltemplate <class Integral>
3867a984708SDavid Chisnall    Integral
387b03f91a8SDavid Chisnall    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
3887a984708SDavid Chisnall
3897a984708SDavid Chisnalltemplate <class Integral>
3907a984708SDavid Chisnall    Integral
391b03f91a8SDavid Chisnall    atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
3927a984708SDavid Chisnall
3937a984708SDavid Chisnalltemplate <class Integral>
3947a984708SDavid Chisnall    Integral
3957a984708SDavid Chisnall    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
396b03f91a8SDavid Chisnall                              memory_order m) noexcept;
3977a984708SDavid Chisnalltemplate <class Integral>
3987a984708SDavid Chisnall    Integral
3997a984708SDavid Chisnall    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
400b03f91a8SDavid Chisnall                              memory_order m) noexcept;
4017a984708SDavid Chisnalltemplate <class Integral>
4027a984708SDavid Chisnall    Integral
403b03f91a8SDavid Chisnall    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
4047a984708SDavid Chisnall
4057a984708SDavid Chisnalltemplate <class Integral>
4067a984708SDavid Chisnall    Integral
407b03f91a8SDavid Chisnall    atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
4087a984708SDavid Chisnall
4097a984708SDavid Chisnalltemplate <class Integral>
4107a984708SDavid Chisnall    Integral
4117a984708SDavid Chisnall    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
412b03f91a8SDavid Chisnall                              memory_order m) noexcept;
4137a984708SDavid Chisnalltemplate <class Integral>
4147a984708SDavid Chisnall    Integral
4157a984708SDavid Chisnall    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
416b03f91a8SDavid Chisnall                              memory_order m) noexcept;
4177a984708SDavid Chisnalltemplate <class Integral>
4187a984708SDavid Chisnall    Integral
419b03f91a8SDavid Chisnall    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
4207a984708SDavid Chisnall
4217a984708SDavid Chisnalltemplate <class Integral>
4227a984708SDavid Chisnall    Integral
423b03f91a8SDavid Chisnall    atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
4247a984708SDavid Chisnall
4257a984708SDavid Chisnalltemplate <class Integral>
4267a984708SDavid Chisnall    Integral
4277a984708SDavid Chisnall    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
428b03f91a8SDavid Chisnall                             memory_order m) noexcept;
4297a984708SDavid Chisnalltemplate <class Integral>
4307a984708SDavid Chisnall    Integral
4317a984708SDavid Chisnall    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
432b03f91a8SDavid Chisnall                             memory_order m) noexcept;
4337a984708SDavid Chisnalltemplate <class Integral>
4347a984708SDavid Chisnall    Integral
435b03f91a8SDavid Chisnall    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
4367a984708SDavid Chisnall
4377a984708SDavid Chisnalltemplate <class Integral>
4387a984708SDavid Chisnall    Integral
439b03f91a8SDavid Chisnall    atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
4407a984708SDavid Chisnall
4417a984708SDavid Chisnalltemplate <class Integral>
4427a984708SDavid Chisnall    Integral
4437a984708SDavid Chisnall    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
444b03f91a8SDavid Chisnall                              memory_order m) noexcept;
4457a984708SDavid Chisnalltemplate <class Integral>
4467a984708SDavid Chisnall    Integral
4477a984708SDavid Chisnall    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
448b03f91a8SDavid Chisnall                              memory_order m) noexcept;
4497a984708SDavid Chisnall
4507a984708SDavid Chisnalltemplate <class T>
4517a984708SDavid Chisnall    T*
452b03f91a8SDavid Chisnall    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
4537a984708SDavid Chisnall
4547a984708SDavid Chisnalltemplate <class T>
4557a984708SDavid Chisnall    T*
456b03f91a8SDavid Chisnall    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
4577a984708SDavid Chisnall
4587a984708SDavid Chisnalltemplate <class T>
4597a984708SDavid Chisnall    T*
4607a984708SDavid Chisnall    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
461b03f91a8SDavid Chisnall                              memory_order m) noexcept;
4627a984708SDavid Chisnalltemplate <class T>
4637a984708SDavid Chisnall    T*
464b03f91a8SDavid Chisnall    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
4657a984708SDavid Chisnall
4667a984708SDavid Chisnalltemplate <class T>
4677a984708SDavid Chisnall    T*
468b03f91a8SDavid Chisnall    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
4697a984708SDavid Chisnall
4707a984708SDavid Chisnalltemplate <class T>
4717a984708SDavid Chisnall    T*
472b03f91a8SDavid Chisnall    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
4737a984708SDavid Chisnall
4747a984708SDavid Chisnalltemplate <class T>
4757a984708SDavid Chisnall    T*
4767a984708SDavid Chisnall    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
477b03f91a8SDavid Chisnall                              memory_order m) noexcept;
4787a984708SDavid Chisnalltemplate <class T>
4797a984708SDavid Chisnall    T*
480b03f91a8SDavid Chisnall    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
4817a984708SDavid Chisnall
4827a984708SDavid Chisnall// Atomics for standard typedef types
4837a984708SDavid Chisnall
484cfdf2879SDavid Chisnalltypedef atomic<bool>               atomic_bool;
4857a984708SDavid Chisnalltypedef atomic<char>               atomic_char;
4867a984708SDavid Chisnalltypedef atomic<signed char>        atomic_schar;
4877a984708SDavid Chisnalltypedef atomic<unsigned char>      atomic_uchar;
4887a984708SDavid Chisnalltypedef atomic<short>              atomic_short;
4897a984708SDavid Chisnalltypedef atomic<unsigned short>     atomic_ushort;
4907a984708SDavid Chisnalltypedef atomic<int>                atomic_int;
4917a984708SDavid Chisnalltypedef atomic<unsigned int>       atomic_uint;
4927a984708SDavid Chisnalltypedef atomic<long>               atomic_long;
4937a984708SDavid Chisnalltypedef atomic<unsigned long>      atomic_ulong;
4947a984708SDavid Chisnalltypedef atomic<long long>          atomic_llong;
4957a984708SDavid Chisnalltypedef atomic<unsigned long long> atomic_ullong;
4967a984708SDavid Chisnalltypedef atomic<char16_t>           atomic_char16_t;
4977a984708SDavid Chisnalltypedef atomic<char32_t>           atomic_char32_t;
4987a984708SDavid Chisnalltypedef atomic<wchar_t>            atomic_wchar_t;
4997a984708SDavid Chisnall
5007a984708SDavid Chisnalltypedef atomic<int_least8_t>   atomic_int_least8_t;
5017a984708SDavid Chisnalltypedef atomic<uint_least8_t>  atomic_uint_least8_t;
5027a984708SDavid Chisnalltypedef atomic<int_least16_t>  atomic_int_least16_t;
5037a984708SDavid Chisnalltypedef atomic<uint_least16_t> atomic_uint_least16_t;
5047a984708SDavid Chisnalltypedef atomic<int_least32_t>  atomic_int_least32_t;
5057a984708SDavid Chisnalltypedef atomic<uint_least32_t> atomic_uint_least32_t;
5067a984708SDavid Chisnalltypedef atomic<int_least64_t>  atomic_int_least64_t;
5077a984708SDavid Chisnalltypedef atomic<uint_least64_t> atomic_uint_least64_t;
5087a984708SDavid Chisnall
5097a984708SDavid Chisnalltypedef atomic<int_fast8_t>   atomic_int_fast8_t;
5107a984708SDavid Chisnalltypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
5117a984708SDavid Chisnalltypedef atomic<int_fast16_t>  atomic_int_fast16_t;
5127a984708SDavid Chisnalltypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
5137a984708SDavid Chisnalltypedef atomic<int_fast32_t>  atomic_int_fast32_t;
5147a984708SDavid Chisnalltypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
5157a984708SDavid Chisnalltypedef atomic<int_fast64_t>  atomic_int_fast64_t;
5167a984708SDavid Chisnalltypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
5177a984708SDavid Chisnall
5187c82a1ecSDimitry Andrictypedef atomic<int8_t>   atomic_int8_t;
5197c82a1ecSDimitry Andrictypedef atomic<uint8_t>  atomic_uint8_t;
5207c82a1ecSDimitry Andrictypedef atomic<int16_t>  atomic_int16_t;
5217c82a1ecSDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t;
5227c82a1ecSDimitry Andrictypedef atomic<int32_t>  atomic_int32_t;
5237c82a1ecSDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t;
5247c82a1ecSDimitry Andrictypedef atomic<int64_t>  atomic_int64_t;
5257c82a1ecSDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t;
5267c82a1ecSDimitry Andric
5277a984708SDavid Chisnalltypedef atomic<intptr_t>  atomic_intptr_t;
5287a984708SDavid Chisnalltypedef atomic<uintptr_t> atomic_uintptr_t;
5297a984708SDavid Chisnalltypedef atomic<size_t>    atomic_size_t;
5307a984708SDavid Chisnalltypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
5317a984708SDavid Chisnalltypedef atomic<intmax_t>  atomic_intmax_t;
5327a984708SDavid Chisnalltypedef atomic<uintmax_t> atomic_uintmax_t;
5337a984708SDavid Chisnall
5347a984708SDavid Chisnall// fences
5357a984708SDavid Chisnall
536b03f91a8SDavid Chisnallvoid atomic_thread_fence(memory_order m) noexcept;
537b03f91a8SDavid Chisnallvoid atomic_signal_fence(memory_order m) noexcept;
5387a984708SDavid Chisnall
5397a984708SDavid Chisnall}  // std
5407a984708SDavid Chisnall
5417a984708SDavid Chisnall*/
5427a984708SDavid Chisnall
5437a984708SDavid Chisnall#include <__config>
5447a984708SDavid Chisnall#include <cstddef>
5457a984708SDavid Chisnall#include <cstdint>
5467a984708SDavid Chisnall#include <type_traits>
547*b5893f02SDimitry Andric#include <version>
5487a984708SDavid Chisnall
5497a984708SDavid Chisnall#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5507a984708SDavid Chisnall#pragma GCC system_header
5517a984708SDavid Chisnall#endif
5527a984708SDavid Chisnall
553d72607e9SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
554d72607e9SDimitry Andric#error <atomic> is not supported on this single threaded system
5559729cf09SDimitry Andric#endif
5569729cf09SDimitry Andric#if !defined(_LIBCPP_HAS_C_ATOMIC_IMP) && !defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
5579729cf09SDimitry Andric#error <atomic> is not implemented
5589729cf09SDimitry Andric#endif
5594ba319b5SDimitry Andric#ifdef kill_dependency
5604ba319b5SDimitry Andric#error C++ standard library is incompatible with <stdatomic.h>
5614ba319b5SDimitry Andric#endif
562d72607e9SDimitry Andric
563540d2a8bSDimitry Andric#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
564540d2a8bSDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
565540d2a8bSDimitry Andric                           __m == memory_order_acquire || \
566540d2a8bSDimitry Andric                           __m == memory_order_acq_rel,   \
567540d2a8bSDimitry Andric                        "memory order argument to atomic operation is invalid")
568540d2a8bSDimitry Andric
569540d2a8bSDimitry Andric#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
570540d2a8bSDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
571540d2a8bSDimitry Andric                           __m == memory_order_acq_rel,   \
572540d2a8bSDimitry Andric                        "memory order argument to atomic operation is invalid")
573540d2a8bSDimitry Andric
574540d2a8bSDimitry Andric#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
575540d2a8bSDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
576540d2a8bSDimitry Andric                           __f == memory_order_acq_rel,   \
577540d2a8bSDimitry Andric                        "memory order argument to atomic operation is invalid")
578540d2a8bSDimitry Andric
5797a984708SDavid Chisnall_LIBCPP_BEGIN_NAMESPACE_STD
5807a984708SDavid Chisnall
5817a984708SDavid Chisnalltypedef enum memory_order
5827a984708SDavid Chisnall{
5837a984708SDavid Chisnall    memory_order_relaxed, memory_order_consume, memory_order_acquire,
5847a984708SDavid Chisnall    memory_order_release, memory_order_acq_rel, memory_order_seq_cst
5857a984708SDavid Chisnall} memory_order;
5867a984708SDavid Chisnall
5879729cf09SDimitry Andric#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
588d72607e9SDimitry Andricnamespace __gcc_atomic {
589854fa44bSDimitry Andrictemplate <typename _Tp>
590d72607e9SDimitry Andricstruct __gcc_atomic_t {
59191325990SDimitry Andric
59291325990SDimitry Andric#if _GNUC_VER >= 501
59391325990SDimitry Andric    static_assert(is_trivially_copyable<_Tp>::value,
59491325990SDimitry Andric      "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
59591325990SDimitry Andric#endif
59691325990SDimitry Andric
59791325990SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
598aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
59991325990SDimitry Andric    __gcc_atomic_t() _NOEXCEPT = default;
60091325990SDimitry Andric#else
60191325990SDimitry Andric    __gcc_atomic_t() _NOEXCEPT : __a_value() {}
602aed8d94eSDimitry Andric#endif // _LIBCPP_CXX03_LANG
603854fa44bSDimitry Andric  _LIBCPP_CONSTEXPR explicit __gcc_atomic_t(_Tp value) _NOEXCEPT
604854fa44bSDimitry Andric    : __a_value(value) {}
605854fa44bSDimitry Andric  _Tp __a_value;
606d72607e9SDimitry Andric};
607d72607e9SDimitry Andric#define _Atomic(x) __gcc_atomic::__gcc_atomic_t<x>
608d72607e9SDimitry Andric
609854fa44bSDimitry Andrictemplate <typename _Tp> _Tp __create();
610d72607e9SDimitry Andric
611854fa44bSDimitry Andrictemplate <typename _Tp, typename _Td>
612854fa44bSDimitry Andrictypename enable_if<sizeof(_Tp()->__a_value = __create<_Td>()), char>::type
613d72607e9SDimitry Andric    __test_atomic_assignable(int);
614854fa44bSDimitry Andrictemplate <typename _Tp, typename _Up>
615d72607e9SDimitry Andric__two __test_atomic_assignable(...);
616d72607e9SDimitry Andric
617854fa44bSDimitry Andrictemplate <typename _Tp, typename _Td>
618d72607e9SDimitry Andricstruct __can_assign {
619d72607e9SDimitry Andric  static const bool value =
620854fa44bSDimitry Andric      sizeof(__test_atomic_assignable<_Tp, _Td>(1)) == sizeof(char);
621d72607e9SDimitry Andric};
622d72607e9SDimitry Andric
62391325990SDimitry Andricstatic inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
624d72607e9SDimitry Andric  // Avoid switch statement to make this a constexpr.
625d72607e9SDimitry Andric  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
626d72607e9SDimitry Andric         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
627d72607e9SDimitry Andric          (__order == memory_order_release ? __ATOMIC_RELEASE:
628d72607e9SDimitry Andric           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
629d72607e9SDimitry Andric            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
630d72607e9SDimitry Andric              __ATOMIC_CONSUME))));
631d72607e9SDimitry Andric}
632d72607e9SDimitry Andric
63391325990SDimitry Andricstatic inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
634854fa44bSDimitry Andric  // Avoid switch statement to make this a constexpr.
635854fa44bSDimitry Andric  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
636854fa44bSDimitry Andric         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
637854fa44bSDimitry Andric          (__order == memory_order_release ? __ATOMIC_RELAXED:
638854fa44bSDimitry Andric           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
639854fa44bSDimitry Andric            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
640854fa44bSDimitry Andric              __ATOMIC_CONSUME))));
641854fa44bSDimitry Andric}
642854fa44bSDimitry Andric
643d72607e9SDimitry Andric} // namespace __gcc_atomic
644d72607e9SDimitry Andric
645d72607e9SDimitry Andrictemplate <typename _Tp>
646d72607e9SDimitry Andricstatic inline
647d72607e9SDimitry Andrictypename enable_if<
648d72607e9SDimitry Andric    __gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value>::type
649d72607e9SDimitry Andric__c11_atomic_init(volatile _Atomic(_Tp)* __a,  _Tp __val) {
650d72607e9SDimitry Andric  __a->__a_value = __val;
651d72607e9SDimitry Andric}
652d72607e9SDimitry Andric
653d72607e9SDimitry Andrictemplate <typename _Tp>
654d72607e9SDimitry Andricstatic inline
655d72607e9SDimitry Andrictypename enable_if<
656d72607e9SDimitry Andric    !__gcc_atomic::__can_assign<volatile _Atomic(_Tp)*, _Tp>::value &&
657d72607e9SDimitry Andric     __gcc_atomic::__can_assign<         _Atomic(_Tp)*, _Tp>::value>::type
658d72607e9SDimitry Andric__c11_atomic_init(volatile _Atomic(_Tp)* __a,  _Tp __val) {
659d72607e9SDimitry Andric  // [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
660d72607e9SDimitry Andric  // the default operator= in an object is not volatile, a byte-by-byte copy
661d72607e9SDimitry Andric  // is required.
662d72607e9SDimitry Andric  volatile char* to = reinterpret_cast<volatile char*>(&__a->__a_value);
663d72607e9SDimitry Andric  volatile char* end = to + sizeof(_Tp);
664d72607e9SDimitry Andric  char* from = reinterpret_cast<char*>(&__val);
665d72607e9SDimitry Andric  while (to != end) {
666d72607e9SDimitry Andric    *to++ = *from++;
667d72607e9SDimitry Andric  }
668d72607e9SDimitry Andric}
669d72607e9SDimitry Andric
670d72607e9SDimitry Andrictemplate <typename _Tp>
671d72607e9SDimitry Andricstatic inline void __c11_atomic_init(_Atomic(_Tp)* __a,  _Tp __val) {
672d72607e9SDimitry Andric  __a->__a_value = __val;
673d72607e9SDimitry Andric}
674d72607e9SDimitry Andric
675d72607e9SDimitry Andricstatic inline void __c11_atomic_thread_fence(memory_order __order) {
676d72607e9SDimitry Andric  __atomic_thread_fence(__gcc_atomic::__to_gcc_order(__order));
677d72607e9SDimitry Andric}
678d72607e9SDimitry Andric
679d72607e9SDimitry Andricstatic inline void __c11_atomic_signal_fence(memory_order __order) {
680d72607e9SDimitry Andric  __atomic_signal_fence(__gcc_atomic::__to_gcc_order(__order));
681d72607e9SDimitry Andric}
682d72607e9SDimitry Andric
683d72607e9SDimitry Andrictemplate <typename _Tp>
684d72607e9SDimitry Andricstatic inline void __c11_atomic_store(volatile _Atomic(_Tp)* __a,  _Tp __val,
685d72607e9SDimitry Andric                                      memory_order __order) {
686d72607e9SDimitry Andric  return __atomic_store(&__a->__a_value, &__val,
687d72607e9SDimitry Andric                        __gcc_atomic::__to_gcc_order(__order));
688d72607e9SDimitry Andric}
689d72607e9SDimitry Andric
690d72607e9SDimitry Andrictemplate <typename _Tp>
691d72607e9SDimitry Andricstatic inline void __c11_atomic_store(_Atomic(_Tp)* __a,  _Tp __val,
692d72607e9SDimitry Andric                                      memory_order __order) {
693854fa44bSDimitry Andric  __atomic_store(&__a->__a_value, &__val,
694d72607e9SDimitry Andric                 __gcc_atomic::__to_gcc_order(__order));
695d72607e9SDimitry Andric}
696d72607e9SDimitry Andric
697d72607e9SDimitry Andrictemplate <typename _Tp>
6984ba319b5SDimitry Andricstatic inline _Tp __c11_atomic_load(const volatile _Atomic(_Tp)* __a,
699d72607e9SDimitry Andric                                    memory_order __order) {
700d72607e9SDimitry Andric  _Tp __ret;
701d72607e9SDimitry Andric  __atomic_load(&__a->__a_value, &__ret,
702d72607e9SDimitry Andric                __gcc_atomic::__to_gcc_order(__order));
703d72607e9SDimitry Andric  return __ret;
704d72607e9SDimitry Andric}
705d72607e9SDimitry Andric
706d72607e9SDimitry Andrictemplate <typename _Tp>
7074ba319b5SDimitry Andricstatic inline _Tp __c11_atomic_load(const _Atomic(_Tp)* __a, memory_order __order) {
708d72607e9SDimitry Andric  _Tp __ret;
709d72607e9SDimitry Andric  __atomic_load(&__a->__a_value, &__ret,
710d72607e9SDimitry Andric                __gcc_atomic::__to_gcc_order(__order));
711d72607e9SDimitry Andric  return __ret;
712d72607e9SDimitry Andric}
713d72607e9SDimitry Andric
714d72607e9SDimitry Andrictemplate <typename _Tp>
715d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_exchange(volatile _Atomic(_Tp)* __a,
716d72607e9SDimitry Andric                                        _Tp __value, memory_order __order) {
717d72607e9SDimitry Andric  _Tp __ret;
718d72607e9SDimitry Andric  __atomic_exchange(&__a->__a_value, &__value, &__ret,
719d72607e9SDimitry Andric                    __gcc_atomic::__to_gcc_order(__order));
720d72607e9SDimitry Andric  return __ret;
721d72607e9SDimitry Andric}
722d72607e9SDimitry Andric
723d72607e9SDimitry Andrictemplate <typename _Tp>
724d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_exchange(_Atomic(_Tp)* __a, _Tp __value,
725d72607e9SDimitry Andric                                        memory_order __order) {
726d72607e9SDimitry Andric  _Tp __ret;
727d72607e9SDimitry Andric  __atomic_exchange(&__a->__a_value, &__value, &__ret,
728d72607e9SDimitry Andric                    __gcc_atomic::__to_gcc_order(__order));
729d72607e9SDimitry Andric  return __ret;
730d72607e9SDimitry Andric}
731d72607e9SDimitry Andric
732d72607e9SDimitry Andrictemplate <typename _Tp>
733d72607e9SDimitry Andricstatic inline bool __c11_atomic_compare_exchange_strong(
734d72607e9SDimitry Andric    volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
735d72607e9SDimitry Andric    memory_order __success, memory_order __failure) {
736d72607e9SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
737d72607e9SDimitry Andric                                   false,
738d72607e9SDimitry Andric                                   __gcc_atomic::__to_gcc_order(__success),
739854fa44bSDimitry Andric                                   __gcc_atomic::__to_gcc_failure_order(__failure));
740d72607e9SDimitry Andric}
741d72607e9SDimitry Andric
742d72607e9SDimitry Andrictemplate <typename _Tp>
743d72607e9SDimitry Andricstatic inline bool __c11_atomic_compare_exchange_strong(
744d72607e9SDimitry Andric    _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
745d72607e9SDimitry Andric    memory_order __failure) {
746d72607e9SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
747d72607e9SDimitry Andric                                   false,
748d72607e9SDimitry Andric                                   __gcc_atomic::__to_gcc_order(__success),
749854fa44bSDimitry Andric                                   __gcc_atomic::__to_gcc_failure_order(__failure));
750d72607e9SDimitry Andric}
751d72607e9SDimitry Andric
752d72607e9SDimitry Andrictemplate <typename _Tp>
753d72607e9SDimitry Andricstatic inline bool __c11_atomic_compare_exchange_weak(
754d72607e9SDimitry Andric    volatile _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value,
755d72607e9SDimitry Andric    memory_order __success, memory_order __failure) {
756d72607e9SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
757d72607e9SDimitry Andric                                   true,
758d72607e9SDimitry Andric                                   __gcc_atomic::__to_gcc_order(__success),
759854fa44bSDimitry Andric                                   __gcc_atomic::__to_gcc_failure_order(__failure));
760d72607e9SDimitry Andric}
761d72607e9SDimitry Andric
762d72607e9SDimitry Andrictemplate <typename _Tp>
763d72607e9SDimitry Andricstatic inline bool __c11_atomic_compare_exchange_weak(
764d72607e9SDimitry Andric    _Atomic(_Tp)* __a, _Tp* __expected, _Tp __value, memory_order __success,
765d72607e9SDimitry Andric    memory_order __failure) {
766d72607e9SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
767d72607e9SDimitry Andric                                   true,
768d72607e9SDimitry Andric                                   __gcc_atomic::__to_gcc_order(__success),
769854fa44bSDimitry Andric                                   __gcc_atomic::__to_gcc_failure_order(__failure));
770d72607e9SDimitry Andric}
771d72607e9SDimitry Andric
772d72607e9SDimitry Andrictemplate <typename _Tp>
773d72607e9SDimitry Andricstruct __skip_amt { enum {value = 1}; };
774d72607e9SDimitry Andric
775d72607e9SDimitry Andrictemplate <typename _Tp>
776d72607e9SDimitry Andricstruct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
777d72607e9SDimitry Andric
778d72607e9SDimitry Andric// FIXME: Haven't figured out what the spec says about using arrays with
779d72607e9SDimitry Andric// atomic_fetch_add. Force a failure rather than creating bad behavior.
780d72607e9SDimitry Andrictemplate <typename _Tp>
781d72607e9SDimitry Andricstruct __skip_amt<_Tp[]> { };
782d72607e9SDimitry Andrictemplate <typename _Tp, int n>
783d72607e9SDimitry Andricstruct __skip_amt<_Tp[n]> { };
784d72607e9SDimitry Andric
785d72607e9SDimitry Andrictemplate <typename _Tp, typename _Td>
786d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_add(volatile _Atomic(_Tp)* __a,
787d72607e9SDimitry Andric                                         _Td __delta, memory_order __order) {
788d72607e9SDimitry Andric  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
789d72607e9SDimitry Andric                            __gcc_atomic::__to_gcc_order(__order));
790d72607e9SDimitry Andric}
791d72607e9SDimitry Andric
792d72607e9SDimitry Andrictemplate <typename _Tp, typename _Td>
793d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_add(_Atomic(_Tp)* __a, _Td __delta,
794d72607e9SDimitry Andric                                         memory_order __order) {
795d72607e9SDimitry Andric  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
796d72607e9SDimitry Andric                            __gcc_atomic::__to_gcc_order(__order));
797d72607e9SDimitry Andric}
798d72607e9SDimitry Andric
799d72607e9SDimitry Andrictemplate <typename _Tp, typename _Td>
800d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_sub(volatile _Atomic(_Tp)* __a,
801d72607e9SDimitry Andric                                         _Td __delta, memory_order __order) {
802d72607e9SDimitry Andric  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
803d72607e9SDimitry Andric                            __gcc_atomic::__to_gcc_order(__order));
804d72607e9SDimitry Andric}
805d72607e9SDimitry Andric
806d72607e9SDimitry Andrictemplate <typename _Tp, typename _Td>
807d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_sub(_Atomic(_Tp)* __a, _Td __delta,
808d72607e9SDimitry Andric                                         memory_order __order) {
809d72607e9SDimitry Andric  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
810d72607e9SDimitry Andric                            __gcc_atomic::__to_gcc_order(__order));
811d72607e9SDimitry Andric}
812d72607e9SDimitry Andric
813d72607e9SDimitry Andrictemplate <typename _Tp>
814d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_and(volatile _Atomic(_Tp)* __a,
815d72607e9SDimitry Andric                                         _Tp __pattern, memory_order __order) {
816d72607e9SDimitry Andric  return __atomic_fetch_and(&__a->__a_value, __pattern,
817d72607e9SDimitry Andric                            __gcc_atomic::__to_gcc_order(__order));
818d72607e9SDimitry Andric}
819d72607e9SDimitry Andric
820d72607e9SDimitry Andrictemplate <typename _Tp>
821d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_and(_Atomic(_Tp)* __a,
822d72607e9SDimitry Andric                                         _Tp __pattern, memory_order __order) {
823d72607e9SDimitry Andric  return __atomic_fetch_and(&__a->__a_value, __pattern,
824d72607e9SDimitry Andric                            __gcc_atomic::__to_gcc_order(__order));
825d72607e9SDimitry Andric}
826d72607e9SDimitry Andric
827d72607e9SDimitry Andrictemplate <typename _Tp>
828d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_or(volatile _Atomic(_Tp)* __a,
829d72607e9SDimitry Andric                                        _Tp __pattern, memory_order __order) {
830d72607e9SDimitry Andric  return __atomic_fetch_or(&__a->__a_value, __pattern,
831d72607e9SDimitry Andric                           __gcc_atomic::__to_gcc_order(__order));
832d72607e9SDimitry Andric}
833d72607e9SDimitry Andric
834d72607e9SDimitry Andrictemplate <typename _Tp>
835d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_or(_Atomic(_Tp)* __a, _Tp __pattern,
836d72607e9SDimitry Andric                                        memory_order __order) {
837d72607e9SDimitry Andric  return __atomic_fetch_or(&__a->__a_value, __pattern,
838d72607e9SDimitry Andric                           __gcc_atomic::__to_gcc_order(__order));
839d72607e9SDimitry Andric}
840d72607e9SDimitry Andric
841d72607e9SDimitry Andrictemplate <typename _Tp>
842d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_xor(volatile _Atomic(_Tp)* __a,
843d72607e9SDimitry Andric                                         _Tp __pattern, memory_order __order) {
844d72607e9SDimitry Andric  return __atomic_fetch_xor(&__a->__a_value, __pattern,
845d72607e9SDimitry Andric                            __gcc_atomic::__to_gcc_order(__order));
846d72607e9SDimitry Andric}
847d72607e9SDimitry Andric
848d72607e9SDimitry Andrictemplate <typename _Tp>
849d72607e9SDimitry Andricstatic inline _Tp __c11_atomic_fetch_xor(_Atomic(_Tp)* __a, _Tp __pattern,
850d72607e9SDimitry Andric                                         memory_order __order) {
851d72607e9SDimitry Andric  return __atomic_fetch_xor(&__a->__a_value, __pattern,
852d72607e9SDimitry Andric                            __gcc_atomic::__to_gcc_order(__order));
853d72607e9SDimitry Andric}
8549729cf09SDimitry Andric#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP
855d72607e9SDimitry Andric
8567a984708SDavid Chisnalltemplate <class _Tp>
8577a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
8587a984708SDavid Chisnall_Tp
859b03f91a8SDavid Chisnallkill_dependency(_Tp __y) _NOEXCEPT
8607a984708SDavid Chisnall{
8617a984708SDavid Chisnall    return __y;
8627a984708SDavid Chisnall}
8637a984708SDavid Chisnall
86451690af2SDimitry Andric#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
86551690af2SDimitry Andric# define ATOMIC_BOOL_LOCK_FREE      __CLANG_ATOMIC_BOOL_LOCK_FREE
86651690af2SDimitry Andric# define ATOMIC_CHAR_LOCK_FREE      __CLANG_ATOMIC_CHAR_LOCK_FREE
86751690af2SDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE  __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
86851690af2SDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE  __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
86951690af2SDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE   __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
87051690af2SDimitry Andric# define ATOMIC_SHORT_LOCK_FREE     __CLANG_ATOMIC_SHORT_LOCK_FREE
87151690af2SDimitry Andric# define ATOMIC_INT_LOCK_FREE       __CLANG_ATOMIC_INT_LOCK_FREE
87251690af2SDimitry Andric# define ATOMIC_LONG_LOCK_FREE      __CLANG_ATOMIC_LONG_LOCK_FREE
87351690af2SDimitry Andric# define ATOMIC_LLONG_LOCK_FREE     __CLANG_ATOMIC_LLONG_LOCK_FREE
87451690af2SDimitry Andric# define ATOMIC_POINTER_LOCK_FREE   __CLANG_ATOMIC_POINTER_LOCK_FREE
87551690af2SDimitry Andric#else
8767c82a1ecSDimitry Andric# define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
8777c82a1ecSDimitry Andric# define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
8787c82a1ecSDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
8797c82a1ecSDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
8807c82a1ecSDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
8817c82a1ecSDimitry Andric# define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
8827c82a1ecSDimitry Andric# define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
8837c82a1ecSDimitry Andric# define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
8847c82a1ecSDimitry Andric# define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
8857c82a1ecSDimitry Andric# define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
88651690af2SDimitry Andric#endif
8877c82a1ecSDimitry Andric
8887a984708SDavid Chisnall// general atomic<T>
8897a984708SDavid Chisnall
8907a984708SDavid Chisnalltemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
8917a984708SDavid Chisnallstruct __atomic_base  // false
8927a984708SDavid Chisnall{
893936e9439SDimitry Andric    mutable _Atomic(_Tp) __a_;
8947a984708SDavid Chisnall
8957c82a1ecSDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free)
8967c82a1ecSDimitry Andric  static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
8977c82a1ecSDimitry Andric#endif
8987c82a1ecSDimitry Andric
8997a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
900b03f91a8SDavid Chisnall    bool is_lock_free() const volatile _NOEXCEPT
901854fa44bSDimitry Andric    {
9029729cf09SDimitry Andric#if defined(_LIBCPP_HAS_C_ATOMIC_IMP)
903854fa44bSDimitry Andric    return __c11_atomic_is_lock_free(sizeof(_Tp));
904854fa44bSDimitry Andric#else
905854fa44bSDimitry Andric    return __atomic_is_lock_free(sizeof(_Tp), 0);
906854fa44bSDimitry Andric#endif
907854fa44bSDimitry Andric    }
9087a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
909b03f91a8SDavid Chisnall    bool is_lock_free() const _NOEXCEPT
910854fa44bSDimitry Andric        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
9117a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
912b03f91a8SDavid Chisnall    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
913540d2a8bSDimitry Andric      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
914b03f91a8SDavid Chisnall        {__c11_atomic_store(&__a_, __d, __m);}
9157a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
916b03f91a8SDavid Chisnall    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
917540d2a8bSDimitry Andric      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
918b03f91a8SDavid Chisnall        {__c11_atomic_store(&__a_, __d, __m);}
9197a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
920b03f91a8SDavid Chisnall    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
921540d2a8bSDimitry Andric      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
922b03f91a8SDavid Chisnall        {return __c11_atomic_load(&__a_, __m);}
9237a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
924b03f91a8SDavid Chisnall    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
925540d2a8bSDimitry Andric      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
926b03f91a8SDavid Chisnall        {return __c11_atomic_load(&__a_, __m);}
9277a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
928b03f91a8SDavid Chisnall    operator _Tp() const volatile _NOEXCEPT {return load();}
9297a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
930b03f91a8SDavid Chisnall    operator _Tp() const _NOEXCEPT          {return load();}
9317a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
932b03f91a8SDavid Chisnall    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
933b03f91a8SDavid Chisnall        {return __c11_atomic_exchange(&__a_, __d, __m);}
9347a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
935b03f91a8SDavid Chisnall    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
936b03f91a8SDavid Chisnall        {return __c11_atomic_exchange(&__a_, __d, __m);}
9377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9387a984708SDavid Chisnall    bool compare_exchange_weak(_Tp& __e, _Tp __d,
939b03f91a8SDavid Chisnall                               memory_order __s, memory_order __f) volatile _NOEXCEPT
940540d2a8bSDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
941b03f91a8SDavid Chisnall        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
9427a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9437a984708SDavid Chisnall    bool compare_exchange_weak(_Tp& __e, _Tp __d,
944b03f91a8SDavid Chisnall                               memory_order __s, memory_order __f) _NOEXCEPT
945540d2a8bSDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
946b03f91a8SDavid Chisnall        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
9477a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9487a984708SDavid Chisnall    bool compare_exchange_strong(_Tp& __e, _Tp __d,
949b03f91a8SDavid Chisnall                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
950540d2a8bSDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
951b03f91a8SDavid Chisnall        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
9527a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9537a984708SDavid Chisnall    bool compare_exchange_strong(_Tp& __e, _Tp __d,
954b03f91a8SDavid Chisnall                                 memory_order __s, memory_order __f) _NOEXCEPT
955540d2a8bSDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
956b03f91a8SDavid Chisnall        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
9577a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9587a984708SDavid Chisnall    bool compare_exchange_weak(_Tp& __e, _Tp __d,
959b03f91a8SDavid Chisnall                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
960b03f91a8SDavid Chisnall        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
9617a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9627a984708SDavid Chisnall    bool compare_exchange_weak(_Tp& __e, _Tp __d,
963b03f91a8SDavid Chisnall                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
964b03f91a8SDavid Chisnall        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
9657a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9667a984708SDavid Chisnall    bool compare_exchange_strong(_Tp& __e, _Tp __d,
967b03f91a8SDavid Chisnall                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
968b03f91a8SDavid Chisnall        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
9697a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
9707a984708SDavid Chisnall    bool compare_exchange_strong(_Tp& __e, _Tp __d,
971b03f91a8SDavid Chisnall                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
972b03f91a8SDavid Chisnall        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
9737a984708SDavid Chisnall
9747a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
975aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9764bab9fd9SDavid Chisnall    __atomic_base() _NOEXCEPT = default;
9774bab9fd9SDavid Chisnall#else
9784bab9fd9SDavid Chisnall    __atomic_base() _NOEXCEPT : __a_() {}
979aed8d94eSDimitry Andric#endif // _LIBCPP_CXX03_LANG
9804bab9fd9SDavid Chisnall
9817a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
982b03f91a8SDavid Chisnall    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
98380779b37SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9847a984708SDavid Chisnall    __atomic_base(const __atomic_base&) = delete;
9857a984708SDavid Chisnall    __atomic_base& operator=(const __atomic_base&) = delete;
9867a984708SDavid Chisnall    __atomic_base& operator=(const __atomic_base&) volatile = delete;
98780779b37SDimitry Andric#else
9887a984708SDavid Chisnallprivate:
9897a984708SDavid Chisnall    __atomic_base(const __atomic_base&);
9907a984708SDavid Chisnall    __atomic_base& operator=(const __atomic_base&);
9917a984708SDavid Chisnall    __atomic_base& operator=(const __atomic_base&) volatile;
99280779b37SDimitry Andric#endif
9937a984708SDavid Chisnall};
9947a984708SDavid Chisnall
9957c82a1ecSDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free)
9967c82a1ecSDimitry Andrictemplate <class _Tp, bool __b>
9977c82a1ecSDimitry Andric_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
9987c82a1ecSDimitry Andric#endif
9997c82a1ecSDimitry Andric
10007a984708SDavid Chisnall// atomic<Integral>
10017a984708SDavid Chisnall
10027a984708SDavid Chisnalltemplate <class _Tp>
10037a984708SDavid Chisnallstruct __atomic_base<_Tp, true>
10047a984708SDavid Chisnall    : public __atomic_base<_Tp, false>
10057a984708SDavid Chisnall{
10067a984708SDavid Chisnall    typedef __atomic_base<_Tp, false> __base;
10077a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
10084bab9fd9SDavid Chisnall    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
10097a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1010b03f91a8SDavid Chisnall    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
10117a984708SDavid Chisnall
10127a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1013b03f91a8SDavid Chisnall    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1014b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
10157a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1016b03f91a8SDavid Chisnall    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1017b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
10187a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1019b03f91a8SDavid Chisnall    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1020b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
10217a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1022b03f91a8SDavid Chisnall    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1023b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
10247a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1025b03f91a8SDavid Chisnall    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1026b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
10277a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1028b03f91a8SDavid Chisnall    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1029b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
10307a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1031b03f91a8SDavid Chisnall    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1032b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
10337a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1034b03f91a8SDavid Chisnall    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1035b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
10367a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1037b03f91a8SDavid Chisnall    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1038b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
10397a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1040b03f91a8SDavid Chisnall    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1041b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
10427a984708SDavid Chisnall
10437a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1044b03f91a8SDavid Chisnall    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
10457a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1046b03f91a8SDavid Chisnall    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
10477a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1048b03f91a8SDavid Chisnall    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
10497a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1050b03f91a8SDavid Chisnall    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
10517a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1052b03f91a8SDavid Chisnall    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
10537a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1054b03f91a8SDavid Chisnall    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
10557a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1056b03f91a8SDavid Chisnall    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
10577a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1058b03f91a8SDavid Chisnall    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
10597a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1060b03f91a8SDavid Chisnall    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
10617a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1062b03f91a8SDavid Chisnall    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
10637a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1064b03f91a8SDavid Chisnall    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
10657a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1066b03f91a8SDavid Chisnall    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
10677a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1068b03f91a8SDavid Chisnall    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
10697a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1070b03f91a8SDavid Chisnall    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
10717a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1072b03f91a8SDavid Chisnall    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
10737a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1074b03f91a8SDavid Chisnall    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
10757a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1076b03f91a8SDavid Chisnall    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
10777a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1078b03f91a8SDavid Chisnall    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
10797a984708SDavid Chisnall};
10807a984708SDavid Chisnall
10817a984708SDavid Chisnall// atomic<T>
10827a984708SDavid Chisnall
10837a984708SDavid Chisnalltemplate <class _Tp>
10847a984708SDavid Chisnallstruct atomic
10857a984708SDavid Chisnall    : public __atomic_base<_Tp>
10867a984708SDavid Chisnall{
10877a984708SDavid Chisnall    typedef __atomic_base<_Tp> __base;
10887a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
10894bab9fd9SDavid Chisnall    atomic() _NOEXCEPT _LIBCPP_DEFAULT
10907a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1091b03f91a8SDavid Chisnall    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
10927a984708SDavid Chisnall
10937a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1094b03f91a8SDavid Chisnall    _Tp operator=(_Tp __d) volatile _NOEXCEPT
10957a984708SDavid Chisnall        {__base::store(__d); return __d;}
10967a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1097b03f91a8SDavid Chisnall    _Tp operator=(_Tp __d) _NOEXCEPT
10987a984708SDavid Chisnall        {__base::store(__d); return __d;}
10997a984708SDavid Chisnall};
11007a984708SDavid Chisnall
11017a984708SDavid Chisnall// atomic<T*>
11027a984708SDavid Chisnall
11037a984708SDavid Chisnalltemplate <class _Tp>
11047a984708SDavid Chisnallstruct atomic<_Tp*>
11057a984708SDavid Chisnall    : public __atomic_base<_Tp*>
11067a984708SDavid Chisnall{
11077a984708SDavid Chisnall    typedef __atomic_base<_Tp*> __base;
11087a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
11094bab9fd9SDavid Chisnall    atomic() _NOEXCEPT _LIBCPP_DEFAULT
11107a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1111b03f91a8SDavid Chisnall    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
11127a984708SDavid Chisnall
11137a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1114b03f91a8SDavid Chisnall    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
11157a984708SDavid Chisnall        {__base::store(__d); return __d;}
11167a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1117b03f91a8SDavid Chisnall    _Tp* operator=(_Tp* __d) _NOEXCEPT
11187a984708SDavid Chisnall        {__base::store(__d); return __d;}
11197a984708SDavid Chisnall
11207a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
11217a984708SDavid Chisnall    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
1122b03f91a8SDavid Chisnall                                                                        volatile _NOEXCEPT
1123b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
11247a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1125b03f91a8SDavid Chisnall    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1126b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
11277a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
11287a984708SDavid Chisnall    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
1129b03f91a8SDavid Chisnall                                                                        volatile _NOEXCEPT
1130b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
11317a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1132b03f91a8SDavid Chisnall    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
1133b03f91a8SDavid Chisnall        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
11347a984708SDavid Chisnall
11357a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1136b03f91a8SDavid Chisnall    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
11377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1138b03f91a8SDavid Chisnall    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
11397a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1140b03f91a8SDavid Chisnall    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
11417a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1142b03f91a8SDavid Chisnall    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
11437a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1144b03f91a8SDavid Chisnall    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
11457a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1146b03f91a8SDavid Chisnall    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
11477a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1148b03f91a8SDavid Chisnall    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
11497a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1150b03f91a8SDavid Chisnall    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
11517a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1152b03f91a8SDavid Chisnall    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
11537a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1154b03f91a8SDavid Chisnall    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
11557a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1156b03f91a8SDavid Chisnall    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
11577a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1158b03f91a8SDavid Chisnall    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
11597a984708SDavid Chisnall};
11607a984708SDavid Chisnall
11617a984708SDavid Chisnall// atomic_is_lock_free
11627a984708SDavid Chisnall
11637a984708SDavid Chisnalltemplate <class _Tp>
11647a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
11657a984708SDavid Chisnallbool
1166b03f91a8SDavid Chisnallatomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
11677a984708SDavid Chisnall{
11687a984708SDavid Chisnall    return __o->is_lock_free();
11697a984708SDavid Chisnall}
11707a984708SDavid Chisnall
11717a984708SDavid Chisnalltemplate <class _Tp>
11727a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
11737a984708SDavid Chisnallbool
1174b03f91a8SDavid Chisnallatomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
11757a984708SDavid Chisnall{
11767a984708SDavid Chisnall    return __o->is_lock_free();
11777a984708SDavid Chisnall}
11787a984708SDavid Chisnall
11797a984708SDavid Chisnall// atomic_init
11807a984708SDavid Chisnall
11817a984708SDavid Chisnalltemplate <class _Tp>
11827a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
11837a984708SDavid Chisnallvoid
1184b03f91a8SDavid Chisnallatomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
11857a984708SDavid Chisnall{
1186b03f91a8SDavid Chisnall    __c11_atomic_init(&__o->__a_, __d);
11877a984708SDavid Chisnall}
11887a984708SDavid Chisnall
11897a984708SDavid Chisnalltemplate <class _Tp>
11907a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
11917a984708SDavid Chisnallvoid
1192b03f91a8SDavid Chisnallatomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
11937a984708SDavid Chisnall{
1194b03f91a8SDavid Chisnall    __c11_atomic_init(&__o->__a_, __d);
11957a984708SDavid Chisnall}
11967a984708SDavid Chisnall
11977a984708SDavid Chisnall// atomic_store
11987a984708SDavid Chisnall
11997a984708SDavid Chisnalltemplate <class _Tp>
12007a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12017a984708SDavid Chisnallvoid
1202b03f91a8SDavid Chisnallatomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
12037a984708SDavid Chisnall{
12047a984708SDavid Chisnall    __o->store(__d);
12057a984708SDavid Chisnall}
12067a984708SDavid Chisnall
12077a984708SDavid Chisnalltemplate <class _Tp>
12087a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12097a984708SDavid Chisnallvoid
1210b03f91a8SDavid Chisnallatomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
12117a984708SDavid Chisnall{
12127a984708SDavid Chisnall    __o->store(__d);
12137a984708SDavid Chisnall}
12147a984708SDavid Chisnall
12157a984708SDavid Chisnall// atomic_store_explicit
12167a984708SDavid Chisnall
12177a984708SDavid Chisnalltemplate <class _Tp>
12187a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12197a984708SDavid Chisnallvoid
1220b03f91a8SDavid Chisnallatomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1221540d2a8bSDimitry Andric  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
12227a984708SDavid Chisnall{
12237a984708SDavid Chisnall    __o->store(__d, __m);
12247a984708SDavid Chisnall}
12257a984708SDavid Chisnall
12267a984708SDavid Chisnalltemplate <class _Tp>
12277a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12287a984708SDavid Chisnallvoid
1229b03f91a8SDavid Chisnallatomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
1230540d2a8bSDimitry Andric  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
12317a984708SDavid Chisnall{
12327a984708SDavid Chisnall    __o->store(__d, __m);
12337a984708SDavid Chisnall}
12347a984708SDavid Chisnall
12357a984708SDavid Chisnall// atomic_load
12367a984708SDavid Chisnall
12377a984708SDavid Chisnalltemplate <class _Tp>
12387a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12397a984708SDavid Chisnall_Tp
1240b03f91a8SDavid Chisnallatomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
12417a984708SDavid Chisnall{
12427a984708SDavid Chisnall    return __o->load();
12437a984708SDavid Chisnall}
12447a984708SDavid Chisnall
12457a984708SDavid Chisnalltemplate <class _Tp>
12467a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12477a984708SDavid Chisnall_Tp
1248b03f91a8SDavid Chisnallatomic_load(const atomic<_Tp>* __o) _NOEXCEPT
12497a984708SDavid Chisnall{
12507a984708SDavid Chisnall    return __o->load();
12517a984708SDavid Chisnall}
12527a984708SDavid Chisnall
12537a984708SDavid Chisnall// atomic_load_explicit
12547a984708SDavid Chisnall
12557a984708SDavid Chisnalltemplate <class _Tp>
12567a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12577a984708SDavid Chisnall_Tp
1258b03f91a8SDavid Chisnallatomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1259540d2a8bSDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
12607a984708SDavid Chisnall{
12617a984708SDavid Chisnall    return __o->load(__m);
12627a984708SDavid Chisnall}
12637a984708SDavid Chisnall
12647a984708SDavid Chisnalltemplate <class _Tp>
12657a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12667a984708SDavid Chisnall_Tp
1267b03f91a8SDavid Chisnallatomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
1268540d2a8bSDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
12697a984708SDavid Chisnall{
12707a984708SDavid Chisnall    return __o->load(__m);
12717a984708SDavid Chisnall}
12727a984708SDavid Chisnall
12737a984708SDavid Chisnall// atomic_exchange
12747a984708SDavid Chisnall
12757a984708SDavid Chisnalltemplate <class _Tp>
12767a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12777a984708SDavid Chisnall_Tp
1278b03f91a8SDavid Chisnallatomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
12797a984708SDavid Chisnall{
12807a984708SDavid Chisnall    return __o->exchange(__d);
12817a984708SDavid Chisnall}
12827a984708SDavid Chisnall
12837a984708SDavid Chisnalltemplate <class _Tp>
12847a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12857a984708SDavid Chisnall_Tp
1286b03f91a8SDavid Chisnallatomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
12877a984708SDavid Chisnall{
12887a984708SDavid Chisnall    return __o->exchange(__d);
12897a984708SDavid Chisnall}
12907a984708SDavid Chisnall
12917a984708SDavid Chisnall// atomic_exchange_explicit
12927a984708SDavid Chisnall
12937a984708SDavid Chisnalltemplate <class _Tp>
12947a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
12957a984708SDavid Chisnall_Tp
1296b03f91a8SDavid Chisnallatomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
12977a984708SDavid Chisnall{
12987a984708SDavid Chisnall    return __o->exchange(__d, __m);
12997a984708SDavid Chisnall}
13007a984708SDavid Chisnall
13017a984708SDavid Chisnalltemplate <class _Tp>
13027a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13037a984708SDavid Chisnall_Tp
1304b03f91a8SDavid Chisnallatomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
13057a984708SDavid Chisnall{
13067a984708SDavid Chisnall    return __o->exchange(__d, __m);
13077a984708SDavid Chisnall}
13087a984708SDavid Chisnall
13097a984708SDavid Chisnall// atomic_compare_exchange_weak
13107a984708SDavid Chisnall
13117a984708SDavid Chisnalltemplate <class _Tp>
13127a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13137a984708SDavid Chisnallbool
1314b03f91a8SDavid Chisnallatomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
13157a984708SDavid Chisnall{
13167a984708SDavid Chisnall    return __o->compare_exchange_weak(*__e, __d);
13177a984708SDavid Chisnall}
13187a984708SDavid Chisnall
13197a984708SDavid Chisnalltemplate <class _Tp>
13207a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13217a984708SDavid Chisnallbool
1322b03f91a8SDavid Chisnallatomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
13237a984708SDavid Chisnall{
13247a984708SDavid Chisnall    return __o->compare_exchange_weak(*__e, __d);
13257a984708SDavid Chisnall}
13267a984708SDavid Chisnall
13277a984708SDavid Chisnall// atomic_compare_exchange_strong
13287a984708SDavid Chisnall
13297a984708SDavid Chisnalltemplate <class _Tp>
13307a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13317a984708SDavid Chisnallbool
1332b03f91a8SDavid Chisnallatomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
13337a984708SDavid Chisnall{
13347a984708SDavid Chisnall    return __o->compare_exchange_strong(*__e, __d);
13357a984708SDavid Chisnall}
13367a984708SDavid Chisnall
13377a984708SDavid Chisnalltemplate <class _Tp>
13387a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13397a984708SDavid Chisnallbool
1340b03f91a8SDavid Chisnallatomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
13417a984708SDavid Chisnall{
13427a984708SDavid Chisnall    return __o->compare_exchange_strong(*__e, __d);
13437a984708SDavid Chisnall}
13447a984708SDavid Chisnall
13457a984708SDavid Chisnall// atomic_compare_exchange_weak_explicit
13467a984708SDavid Chisnall
13477a984708SDavid Chisnalltemplate <class _Tp>
13487a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13497a984708SDavid Chisnallbool
13507a984708SDavid Chisnallatomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
13517a984708SDavid Chisnall                                      _Tp __d,
1352b03f91a8SDavid Chisnall                                      memory_order __s, memory_order __f) _NOEXCEPT
1353540d2a8bSDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
13547a984708SDavid Chisnall{
13557a984708SDavid Chisnall    return __o->compare_exchange_weak(*__e, __d, __s, __f);
13567a984708SDavid Chisnall}
13577a984708SDavid Chisnall
13587a984708SDavid Chisnalltemplate <class _Tp>
13597a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13607a984708SDavid Chisnallbool
13617a984708SDavid Chisnallatomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
1362b03f91a8SDavid Chisnall                                      memory_order __s, memory_order __f) _NOEXCEPT
1363540d2a8bSDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
13647a984708SDavid Chisnall{
13657a984708SDavid Chisnall    return __o->compare_exchange_weak(*__e, __d, __s, __f);
13667a984708SDavid Chisnall}
13677a984708SDavid Chisnall
13687a984708SDavid Chisnall// atomic_compare_exchange_strong_explicit
13697a984708SDavid Chisnall
13707a984708SDavid Chisnalltemplate <class _Tp>
13717a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13727a984708SDavid Chisnallbool
13737a984708SDavid Chisnallatomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
13747a984708SDavid Chisnall                                        _Tp* __e, _Tp __d,
1375b03f91a8SDavid Chisnall                                        memory_order __s, memory_order __f) _NOEXCEPT
1376540d2a8bSDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
13777a984708SDavid Chisnall{
13787a984708SDavid Chisnall    return __o->compare_exchange_strong(*__e, __d, __s, __f);
13797a984708SDavid Chisnall}
13807a984708SDavid Chisnall
13817a984708SDavid Chisnalltemplate <class _Tp>
13827a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13837a984708SDavid Chisnallbool
13847a984708SDavid Chisnallatomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
13857a984708SDavid Chisnall                                        _Tp __d,
1386b03f91a8SDavid Chisnall                                        memory_order __s, memory_order __f) _NOEXCEPT
1387540d2a8bSDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
13887a984708SDavid Chisnall{
13897a984708SDavid Chisnall    return __o->compare_exchange_strong(*__e, __d, __s, __f);
13907a984708SDavid Chisnall}
13917a984708SDavid Chisnall
13927a984708SDavid Chisnall// atomic_fetch_add
13937a984708SDavid Chisnall
13947a984708SDavid Chisnalltemplate <class _Tp>
13957a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
13967a984708SDavid Chisnalltypename enable_if
13977a984708SDavid Chisnall<
13987a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
13997a984708SDavid Chisnall    _Tp
14007a984708SDavid Chisnall>::type
1401b03f91a8SDavid Chisnallatomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
14027a984708SDavid Chisnall{
14037a984708SDavid Chisnall    return __o->fetch_add(__op);
14047a984708SDavid Chisnall}
14057a984708SDavid Chisnall
14067a984708SDavid Chisnalltemplate <class _Tp>
14077a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
14087a984708SDavid Chisnalltypename enable_if
14097a984708SDavid Chisnall<
14107a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
14117a984708SDavid Chisnall    _Tp
14127a984708SDavid Chisnall>::type
1413b03f91a8SDavid Chisnallatomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
14147a984708SDavid Chisnall{
14157a984708SDavid Chisnall    return __o->fetch_add(__op);
14167a984708SDavid Chisnall}
14177a984708SDavid Chisnall
14187a984708SDavid Chisnalltemplate <class _Tp>
14197a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
14207a984708SDavid Chisnall_Tp*
1421b03f91a8SDavid Chisnallatomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
14227a984708SDavid Chisnall{
14237a984708SDavid Chisnall    return __o->fetch_add(__op);
14247a984708SDavid Chisnall}
14257a984708SDavid Chisnall
14267a984708SDavid Chisnalltemplate <class _Tp>
14277a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
14287a984708SDavid Chisnall_Tp*
1429b03f91a8SDavid Chisnallatomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
14307a984708SDavid Chisnall{
14317a984708SDavid Chisnall    return __o->fetch_add(__op);
14327a984708SDavid Chisnall}
14337a984708SDavid Chisnall
14347a984708SDavid Chisnall// atomic_fetch_add_explicit
14357a984708SDavid Chisnall
14367a984708SDavid Chisnalltemplate <class _Tp>
14377a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
14387a984708SDavid Chisnalltypename enable_if
14397a984708SDavid Chisnall<
14407a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
14417a984708SDavid Chisnall    _Tp
14427a984708SDavid Chisnall>::type
1443b03f91a8SDavid Chisnallatomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
14447a984708SDavid Chisnall{
14457a984708SDavid Chisnall    return __o->fetch_add(__op, __m);
14467a984708SDavid Chisnall}
14477a984708SDavid Chisnall
14487a984708SDavid Chisnalltemplate <class _Tp>
14497a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
14507a984708SDavid Chisnalltypename enable_if
14517a984708SDavid Chisnall<
14527a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
14537a984708SDavid Chisnall    _Tp
14547a984708SDavid Chisnall>::type
1455b03f91a8SDavid Chisnallatomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
14567a984708SDavid Chisnall{
14577a984708SDavid Chisnall    return __o->fetch_add(__op, __m);
14587a984708SDavid Chisnall}
14597a984708SDavid Chisnall
14607a984708SDavid Chisnalltemplate <class _Tp>
14617a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
14627a984708SDavid Chisnall_Tp*
14637a984708SDavid Chisnallatomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1464b03f91a8SDavid Chisnall                          memory_order __m) _NOEXCEPT
14657a984708SDavid Chisnall{
14667a984708SDavid Chisnall    return __o->fetch_add(__op, __m);
14677a984708SDavid Chisnall}
14687a984708SDavid Chisnall
14697a984708SDavid Chisnalltemplate <class _Tp>
14707a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
14717a984708SDavid Chisnall_Tp*
1472b03f91a8SDavid Chisnallatomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
14737a984708SDavid Chisnall{
14747a984708SDavid Chisnall    return __o->fetch_add(__op, __m);
14757a984708SDavid Chisnall}
14767a984708SDavid Chisnall
14777a984708SDavid Chisnall// atomic_fetch_sub
14787a984708SDavid Chisnall
14797a984708SDavid Chisnalltemplate <class _Tp>
14807a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
14817a984708SDavid Chisnalltypename enable_if
14827a984708SDavid Chisnall<
14837a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
14847a984708SDavid Chisnall    _Tp
14857a984708SDavid Chisnall>::type
1486b03f91a8SDavid Chisnallatomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
14877a984708SDavid Chisnall{
14887a984708SDavid Chisnall    return __o->fetch_sub(__op);
14897a984708SDavid Chisnall}
14907a984708SDavid Chisnall
14917a984708SDavid Chisnalltemplate <class _Tp>
14927a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
14937a984708SDavid Chisnalltypename enable_if
14947a984708SDavid Chisnall<
14957a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
14967a984708SDavid Chisnall    _Tp
14977a984708SDavid Chisnall>::type
1498b03f91a8SDavid Chisnallatomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
14997a984708SDavid Chisnall{
15007a984708SDavid Chisnall    return __o->fetch_sub(__op);
15017a984708SDavid Chisnall}
15027a984708SDavid Chisnall
15037a984708SDavid Chisnalltemplate <class _Tp>
15047a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
15057a984708SDavid Chisnall_Tp*
1506b03f91a8SDavid Chisnallatomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
15077a984708SDavid Chisnall{
15087a984708SDavid Chisnall    return __o->fetch_sub(__op);
15097a984708SDavid Chisnall}
15107a984708SDavid Chisnall
15117a984708SDavid Chisnalltemplate <class _Tp>
15127a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
15137a984708SDavid Chisnall_Tp*
1514b03f91a8SDavid Chisnallatomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
15157a984708SDavid Chisnall{
15167a984708SDavid Chisnall    return __o->fetch_sub(__op);
15177a984708SDavid Chisnall}
15187a984708SDavid Chisnall
15197a984708SDavid Chisnall// atomic_fetch_sub_explicit
15207a984708SDavid Chisnall
15217a984708SDavid Chisnalltemplate <class _Tp>
15227a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
15237a984708SDavid Chisnalltypename enable_if
15247a984708SDavid Chisnall<
15257a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
15267a984708SDavid Chisnall    _Tp
15277a984708SDavid Chisnall>::type
1528b03f91a8SDavid Chisnallatomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
15297a984708SDavid Chisnall{
15307a984708SDavid Chisnall    return __o->fetch_sub(__op, __m);
15317a984708SDavid Chisnall}
15327a984708SDavid Chisnall
15337a984708SDavid Chisnalltemplate <class _Tp>
15347a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
15357a984708SDavid Chisnalltypename enable_if
15367a984708SDavid Chisnall<
15377a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
15387a984708SDavid Chisnall    _Tp
15397a984708SDavid Chisnall>::type
1540b03f91a8SDavid Chisnallatomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
15417a984708SDavid Chisnall{
15427a984708SDavid Chisnall    return __o->fetch_sub(__op, __m);
15437a984708SDavid Chisnall}
15447a984708SDavid Chisnall
15457a984708SDavid Chisnalltemplate <class _Tp>
15467a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
15477a984708SDavid Chisnall_Tp*
15487a984708SDavid Chisnallatomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1549b03f91a8SDavid Chisnall                          memory_order __m) _NOEXCEPT
15507a984708SDavid Chisnall{
15517a984708SDavid Chisnall    return __o->fetch_sub(__op, __m);
15527a984708SDavid Chisnall}
15537a984708SDavid Chisnall
15547a984708SDavid Chisnalltemplate <class _Tp>
15557a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
15567a984708SDavid Chisnall_Tp*
1557b03f91a8SDavid Chisnallatomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
15587a984708SDavid Chisnall{
15597a984708SDavid Chisnall    return __o->fetch_sub(__op, __m);
15607a984708SDavid Chisnall}
15617a984708SDavid Chisnall
15627a984708SDavid Chisnall// atomic_fetch_and
15637a984708SDavid Chisnall
15647a984708SDavid Chisnalltemplate <class _Tp>
15657a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
15667a984708SDavid Chisnalltypename enable_if
15677a984708SDavid Chisnall<
15687a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
15697a984708SDavid Chisnall    _Tp
15707a984708SDavid Chisnall>::type
1571b03f91a8SDavid Chisnallatomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
15727a984708SDavid Chisnall{
15737a984708SDavid Chisnall    return __o->fetch_and(__op);
15747a984708SDavid Chisnall}
15757a984708SDavid Chisnall
15767a984708SDavid Chisnalltemplate <class _Tp>
15777a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
15787a984708SDavid Chisnalltypename enable_if
15797a984708SDavid Chisnall<
15807a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
15817a984708SDavid Chisnall    _Tp
15827a984708SDavid Chisnall>::type
1583b03f91a8SDavid Chisnallatomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
15847a984708SDavid Chisnall{
15857a984708SDavid Chisnall    return __o->fetch_and(__op);
15867a984708SDavid Chisnall}
15877a984708SDavid Chisnall
15887a984708SDavid Chisnall// atomic_fetch_and_explicit
15897a984708SDavid Chisnall
15907a984708SDavid Chisnalltemplate <class _Tp>
15917a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
15927a984708SDavid Chisnalltypename enable_if
15937a984708SDavid Chisnall<
15947a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
15957a984708SDavid Chisnall    _Tp
15967a984708SDavid Chisnall>::type
1597b03f91a8SDavid Chisnallatomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
15987a984708SDavid Chisnall{
15997a984708SDavid Chisnall    return __o->fetch_and(__op, __m);
16007a984708SDavid Chisnall}
16017a984708SDavid Chisnall
16027a984708SDavid Chisnalltemplate <class _Tp>
16037a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
16047a984708SDavid Chisnalltypename enable_if
16057a984708SDavid Chisnall<
16067a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
16077a984708SDavid Chisnall    _Tp
16087a984708SDavid Chisnall>::type
1609b03f91a8SDavid Chisnallatomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
16107a984708SDavid Chisnall{
16117a984708SDavid Chisnall    return __o->fetch_and(__op, __m);
16127a984708SDavid Chisnall}
16137a984708SDavid Chisnall
16147a984708SDavid Chisnall// atomic_fetch_or
16157a984708SDavid Chisnall
16167a984708SDavid Chisnalltemplate <class _Tp>
16177a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
16187a984708SDavid Chisnalltypename enable_if
16197a984708SDavid Chisnall<
16207a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
16217a984708SDavid Chisnall    _Tp
16227a984708SDavid Chisnall>::type
1623b03f91a8SDavid Chisnallatomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
16247a984708SDavid Chisnall{
16257a984708SDavid Chisnall    return __o->fetch_or(__op);
16267a984708SDavid Chisnall}
16277a984708SDavid Chisnall
16287a984708SDavid Chisnalltemplate <class _Tp>
16297a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
16307a984708SDavid Chisnalltypename enable_if
16317a984708SDavid Chisnall<
16327a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
16337a984708SDavid Chisnall    _Tp
16347a984708SDavid Chisnall>::type
1635b03f91a8SDavid Chisnallatomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
16367a984708SDavid Chisnall{
16377a984708SDavid Chisnall    return __o->fetch_or(__op);
16387a984708SDavid Chisnall}
16397a984708SDavid Chisnall
16407a984708SDavid Chisnall// atomic_fetch_or_explicit
16417a984708SDavid Chisnall
16427a984708SDavid Chisnalltemplate <class _Tp>
16437a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
16447a984708SDavid Chisnalltypename enable_if
16457a984708SDavid Chisnall<
16467a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
16477a984708SDavid Chisnall    _Tp
16487a984708SDavid Chisnall>::type
1649b03f91a8SDavid Chisnallatomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
16507a984708SDavid Chisnall{
16517a984708SDavid Chisnall    return __o->fetch_or(__op, __m);
16527a984708SDavid Chisnall}
16537a984708SDavid Chisnall
16547a984708SDavid Chisnalltemplate <class _Tp>
16557a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
16567a984708SDavid Chisnalltypename enable_if
16577a984708SDavid Chisnall<
16587a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
16597a984708SDavid Chisnall    _Tp
16607a984708SDavid Chisnall>::type
1661b03f91a8SDavid Chisnallatomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
16627a984708SDavid Chisnall{
16637a984708SDavid Chisnall    return __o->fetch_or(__op, __m);
16647a984708SDavid Chisnall}
16657a984708SDavid Chisnall
16667a984708SDavid Chisnall// atomic_fetch_xor
16677a984708SDavid Chisnall
16687a984708SDavid Chisnalltemplate <class _Tp>
16697a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
16707a984708SDavid Chisnalltypename enable_if
16717a984708SDavid Chisnall<
16727a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
16737a984708SDavid Chisnall    _Tp
16747a984708SDavid Chisnall>::type
1675b03f91a8SDavid Chisnallatomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
16767a984708SDavid Chisnall{
16777a984708SDavid Chisnall    return __o->fetch_xor(__op);
16787a984708SDavid Chisnall}
16797a984708SDavid Chisnall
16807a984708SDavid Chisnalltemplate <class _Tp>
16817a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
16827a984708SDavid Chisnalltypename enable_if
16837a984708SDavid Chisnall<
16847a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
16857a984708SDavid Chisnall    _Tp
16867a984708SDavid Chisnall>::type
1687b03f91a8SDavid Chisnallatomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
16887a984708SDavid Chisnall{
16897a984708SDavid Chisnall    return __o->fetch_xor(__op);
16907a984708SDavid Chisnall}
16917a984708SDavid Chisnall
16927a984708SDavid Chisnall// atomic_fetch_xor_explicit
16937a984708SDavid Chisnall
16947a984708SDavid Chisnalltemplate <class _Tp>
16957a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
16967a984708SDavid Chisnalltypename enable_if
16977a984708SDavid Chisnall<
16987a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
16997a984708SDavid Chisnall    _Tp
17007a984708SDavid Chisnall>::type
1701b03f91a8SDavid Chisnallatomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
17027a984708SDavid Chisnall{
17037a984708SDavid Chisnall    return __o->fetch_xor(__op, __m);
17047a984708SDavid Chisnall}
17057a984708SDavid Chisnall
17067a984708SDavid Chisnalltemplate <class _Tp>
17077a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
17087a984708SDavid Chisnalltypename enable_if
17097a984708SDavid Chisnall<
17107a984708SDavid Chisnall    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
17117a984708SDavid Chisnall    _Tp
17127a984708SDavid Chisnall>::type
1713b03f91a8SDavid Chisnallatomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
17147a984708SDavid Chisnall{
17157a984708SDavid Chisnall    return __o->fetch_xor(__op, __m);
17167a984708SDavid Chisnall}
17177a984708SDavid Chisnall
17187a984708SDavid Chisnall// flag type and operations
17197a984708SDavid Chisnall
17207a984708SDavid Chisnalltypedef struct atomic_flag
17217a984708SDavid Chisnall{
172294e3ee44SDavid Chisnall    _Atomic(bool) __a_;
17237a984708SDavid Chisnall
17247a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1725b03f91a8SDavid Chisnall    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1726b03f91a8SDavid Chisnall        {return __c11_atomic_exchange(&__a_, true, __m);}
17277a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1728b03f91a8SDavid Chisnall    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1729b03f91a8SDavid Chisnall        {return __c11_atomic_exchange(&__a_, true, __m);}
17307a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1731b03f91a8SDavid Chisnall    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1732b03f91a8SDavid Chisnall        {__c11_atomic_store(&__a_, false, __m);}
17337a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1734b03f91a8SDavid Chisnall    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1735b03f91a8SDavid Chisnall        {__c11_atomic_store(&__a_, false, __m);}
17367a984708SDavid Chisnall
17377a984708SDavid Chisnall    _LIBCPP_INLINE_VISIBILITY
1738aed8d94eSDimitry Andric#ifndef _LIBCPP_CXX03_LANG
17394bab9fd9SDavid Chisnall    atomic_flag() _NOEXCEPT = default;
17404bab9fd9SDavid Chisnall#else
17414bab9fd9SDavid Chisnall    atomic_flag() _NOEXCEPT : __a_() {}
1742aed8d94eSDimitry Andric#endif // _LIBCPP_CXX03_LANG
17434bab9fd9SDavid Chisnall
17444ba319b5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
17457c82a1ecSDimitry Andric    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
17467a984708SDavid Chisnall
174780779b37SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
17487a984708SDavid Chisnall    atomic_flag(const atomic_flag&) = delete;
17497a984708SDavid Chisnall    atomic_flag& operator=(const atomic_flag&) = delete;
17507a984708SDavid Chisnall    atomic_flag& operator=(const atomic_flag&) volatile = delete;
175180779b37SDimitry Andric#else
17527a984708SDavid Chisnallprivate:
17537a984708SDavid Chisnall    atomic_flag(const atomic_flag&);
17547a984708SDavid Chisnall    atomic_flag& operator=(const atomic_flag&);
17557a984708SDavid Chisnall    atomic_flag& operator=(const atomic_flag&) volatile;
175680779b37SDimitry Andric#endif
17577a984708SDavid Chisnall} atomic_flag;
17587a984708SDavid Chisnall
17597a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
17607a984708SDavid Chisnallbool
1761b03f91a8SDavid Chisnallatomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
17627a984708SDavid Chisnall{
17637a984708SDavid Chisnall    return __o->test_and_set();
17647a984708SDavid Chisnall}
17657a984708SDavid Chisnall
17667a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
17677a984708SDavid Chisnallbool
1768b03f91a8SDavid Chisnallatomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
17697a984708SDavid Chisnall{
17707a984708SDavid Chisnall    return __o->test_and_set();
17717a984708SDavid Chisnall}
17727a984708SDavid Chisnall
17737a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
17747a984708SDavid Chisnallbool
1775b03f91a8SDavid Chisnallatomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
17767a984708SDavid Chisnall{
17777a984708SDavid Chisnall    return __o->test_and_set(__m);
17787a984708SDavid Chisnall}
17797a984708SDavid Chisnall
17807a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
17817a984708SDavid Chisnallbool
1782b03f91a8SDavid Chisnallatomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
17837a984708SDavid Chisnall{
17847a984708SDavid Chisnall    return __o->test_and_set(__m);
17857a984708SDavid Chisnall}
17867a984708SDavid Chisnall
17877a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
17887a984708SDavid Chisnallvoid
1789b03f91a8SDavid Chisnallatomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
17907a984708SDavid Chisnall{
17917a984708SDavid Chisnall    __o->clear();
17927a984708SDavid Chisnall}
17937a984708SDavid Chisnall
17947a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
17957a984708SDavid Chisnallvoid
1796b03f91a8SDavid Chisnallatomic_flag_clear(atomic_flag* __o) _NOEXCEPT
17977a984708SDavid Chisnall{
17987a984708SDavid Chisnall    __o->clear();
17997a984708SDavid Chisnall}
18007a984708SDavid Chisnall
18017a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
18027a984708SDavid Chisnallvoid
1803b03f91a8SDavid Chisnallatomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
18047a984708SDavid Chisnall{
18057a984708SDavid Chisnall    __o->clear(__m);
18067a984708SDavid Chisnall}
18077a984708SDavid Chisnall
18087a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
18097a984708SDavid Chisnallvoid
1810b03f91a8SDavid Chisnallatomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
18117a984708SDavid Chisnall{
18127a984708SDavid Chisnall    __o->clear(__m);
18137a984708SDavid Chisnall}
18147a984708SDavid Chisnall
18157a984708SDavid Chisnall// fences
18167a984708SDavid Chisnall
18177a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
18187a984708SDavid Chisnallvoid
1819b03f91a8SDavid Chisnallatomic_thread_fence(memory_order __m) _NOEXCEPT
18207a984708SDavid Chisnall{
1821b03f91a8SDavid Chisnall    __c11_atomic_thread_fence(__m);
18227a984708SDavid Chisnall}
18237a984708SDavid Chisnall
18247a984708SDavid Chisnallinline _LIBCPP_INLINE_VISIBILITY
18257a984708SDavid Chisnallvoid
1826b03f91a8SDavid Chisnallatomic_signal_fence(memory_order __m) _NOEXCEPT
18277a984708SDavid Chisnall{
1828b03f91a8SDavid Chisnall    __c11_atomic_signal_fence(__m);
18297a984708SDavid Chisnall}
18307a984708SDavid Chisnall
18317a984708SDavid Chisnall// Atomics for standard typedef types
18327a984708SDavid Chisnall
1833cfdf2879SDavid Chisnalltypedef atomic<bool>               atomic_bool;
18347a984708SDavid Chisnalltypedef atomic<char>               atomic_char;
18357a984708SDavid Chisnalltypedef atomic<signed char>        atomic_schar;
18367a984708SDavid Chisnalltypedef atomic<unsigned char>      atomic_uchar;
18377a984708SDavid Chisnalltypedef atomic<short>              atomic_short;
18387a984708SDavid Chisnalltypedef atomic<unsigned short>     atomic_ushort;
18397a984708SDavid Chisnalltypedef atomic<int>                atomic_int;
18407a984708SDavid Chisnalltypedef atomic<unsigned int>       atomic_uint;
18417a984708SDavid Chisnalltypedef atomic<long>               atomic_long;
18427a984708SDavid Chisnalltypedef atomic<unsigned long>      atomic_ulong;
18437a984708SDavid Chisnalltypedef atomic<long long>          atomic_llong;
18447a984708SDavid Chisnalltypedef atomic<unsigned long long> atomic_ullong;
18457a984708SDavid Chisnalltypedef atomic<char16_t>           atomic_char16_t;
18467a984708SDavid Chisnalltypedef atomic<char32_t>           atomic_char32_t;
18477a984708SDavid Chisnalltypedef atomic<wchar_t>            atomic_wchar_t;
18487a984708SDavid Chisnall
18497a984708SDavid Chisnalltypedef atomic<int_least8_t>   atomic_int_least8_t;
18507a984708SDavid Chisnalltypedef atomic<uint_least8_t>  atomic_uint_least8_t;
18517a984708SDavid Chisnalltypedef atomic<int_least16_t>  atomic_int_least16_t;
18527a984708SDavid Chisnalltypedef atomic<uint_least16_t> atomic_uint_least16_t;
18537a984708SDavid Chisnalltypedef atomic<int_least32_t>  atomic_int_least32_t;
18547a984708SDavid Chisnalltypedef atomic<uint_least32_t> atomic_uint_least32_t;
18557a984708SDavid Chisnalltypedef atomic<int_least64_t>  atomic_int_least64_t;
18567a984708SDavid Chisnalltypedef atomic<uint_least64_t> atomic_uint_least64_t;
18577a984708SDavid Chisnall
18587a984708SDavid Chisnalltypedef atomic<int_fast8_t>   atomic_int_fast8_t;
18597a984708SDavid Chisnalltypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
18607a984708SDavid Chisnalltypedef atomic<int_fast16_t>  atomic_int_fast16_t;
18617a984708SDavid Chisnalltypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
18627a984708SDavid Chisnalltypedef atomic<int_fast32_t>  atomic_int_fast32_t;
18637a984708SDavid Chisnalltypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
18647a984708SDavid Chisnalltypedef atomic<int_fast64_t>  atomic_int_fast64_t;
18657a984708SDavid Chisnalltypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
18667a984708SDavid Chisnall
18677c82a1ecSDimitry Andrictypedef atomic< int8_t>  atomic_int8_t;
18687c82a1ecSDimitry Andrictypedef atomic<uint8_t>  atomic_uint8_t;
18697c82a1ecSDimitry Andrictypedef atomic< int16_t> atomic_int16_t;
18707c82a1ecSDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t;
18717c82a1ecSDimitry Andrictypedef atomic< int32_t> atomic_int32_t;
18727c82a1ecSDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t;
18737c82a1ecSDimitry Andrictypedef atomic< int64_t> atomic_int64_t;
18747c82a1ecSDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t;
18757c82a1ecSDimitry Andric
18767a984708SDavid Chisnalltypedef atomic<intptr_t>  atomic_intptr_t;
18777a984708SDavid Chisnalltypedef atomic<uintptr_t> atomic_uintptr_t;
18787a984708SDavid Chisnalltypedef atomic<size_t>    atomic_size_t;
18797a984708SDavid Chisnalltypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
18807a984708SDavid Chisnalltypedef atomic<intmax_t>  atomic_intmax_t;
18817a984708SDavid Chisnalltypedef atomic<uintmax_t> atomic_uintmax_t;
18827a984708SDavid Chisnall
18837a984708SDavid Chisnall#define ATOMIC_FLAG_INIT {false}
18847a984708SDavid Chisnall#define ATOMIC_VAR_INIT(__v) {__v}
18857a984708SDavid Chisnall
18867a984708SDavid Chisnall_LIBCPP_END_NAMESPACE_STD
18877a984708SDavid Chisnall
18887a984708SDavid Chisnall#endif  // _LIBCPP_ATOMIC
1889