xref: /freebsd/contrib/llvm-project/libcxx/include/atomic (revision e40139ff33b48b56a24c808b166b04b8ee6f5b21)
10b57cec5SDimitry Andric// -*- C++ -*-
20b57cec5SDimitry Andric//===--------------------------- atomic -----------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_ATOMIC
110b57cec5SDimitry Andric#define _LIBCPP_ATOMIC
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    atomic synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andricnamespace std
170b57cec5SDimitry Andric{
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric// feature test macro
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10
220b57cec5SDimitry Andric
230b57cec5SDimitry Andric // order and consistency
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric enum memory_order: unspecified // enum class in C++20
260b57cec5SDimitry Andric {
270b57cec5SDimitry Andric    relaxed,
280b57cec5SDimitry Andric    consume, // load-consume
290b57cec5SDimitry Andric    acquire, // load-acquire
300b57cec5SDimitry Andric    release, // store-release
310b57cec5SDimitry Andric    acq_rel, // store-release load-acquire
320b57cec5SDimitry Andric    seq_cst // store-release load-acquire
330b57cec5SDimitry Andric };
340b57cec5SDimitry Andric
350b57cec5SDimitry Andric inline constexpr auto memory_order_relaxed = memory_order::relaxed;
360b57cec5SDimitry Andric inline constexpr auto memory_order_consume = memory_order::consume;
370b57cec5SDimitry Andric inline constexpr auto memory_order_acquire = memory_order::acquire;
380b57cec5SDimitry Andric inline constexpr auto memory_order_release = memory_order::release;
390b57cec5SDimitry Andric inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
400b57cec5SDimitry Andric inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
410b57cec5SDimitry Andric
420b57cec5SDimitry Andrictemplate <class T> T kill_dependency(T y) noexcept;
430b57cec5SDimitry Andric
440b57cec5SDimitry Andric// lock-free property
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric#define ATOMIC_BOOL_LOCK_FREE unspecified
470b57cec5SDimitry Andric#define ATOMIC_CHAR_LOCK_FREE unspecified
480b57cec5SDimitry Andric#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
490b57cec5SDimitry Andric#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
500b57cec5SDimitry Andric#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
510b57cec5SDimitry Andric#define ATOMIC_SHORT_LOCK_FREE unspecified
520b57cec5SDimitry Andric#define ATOMIC_INT_LOCK_FREE unspecified
530b57cec5SDimitry Andric#define ATOMIC_LONG_LOCK_FREE unspecified
540b57cec5SDimitry Andric#define ATOMIC_LLONG_LOCK_FREE unspecified
550b57cec5SDimitry Andric#define ATOMIC_POINTER_LOCK_FREE unspecified
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric// flag type and operations
580b57cec5SDimitry Andric
590b57cec5SDimitry Andrictypedef struct atomic_flag
600b57cec5SDimitry Andric{
610b57cec5SDimitry Andric    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
620b57cec5SDimitry Andric    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
630b57cec5SDimitry Andric    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
640b57cec5SDimitry Andric    void clear(memory_order m = memory_order_seq_cst) noexcept;
650b57cec5SDimitry Andric    atomic_flag()  noexcept = default;
660b57cec5SDimitry Andric    atomic_flag(const atomic_flag&) = delete;
670b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) = delete;
680b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile = delete;
690b57cec5SDimitry Andric} atomic_flag;
700b57cec5SDimitry Andric
710b57cec5SDimitry Andricbool
720b57cec5SDimitry Andric    atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
730b57cec5SDimitry Andric
740b57cec5SDimitry Andricbool
750b57cec5SDimitry Andric    atomic_flag_test_and_set(atomic_flag* obj) noexcept;
760b57cec5SDimitry Andric
770b57cec5SDimitry Andricbool
780b57cec5SDimitry Andric    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
790b57cec5SDimitry Andric                                      memory_order m) noexcept;
800b57cec5SDimitry Andric
810b57cec5SDimitry Andricbool
820b57cec5SDimitry Andric    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
830b57cec5SDimitry Andric
840b57cec5SDimitry Andricvoid
850b57cec5SDimitry Andric    atomic_flag_clear(volatile atomic_flag* obj) noexcept;
860b57cec5SDimitry Andric
870b57cec5SDimitry Andricvoid
880b57cec5SDimitry Andric    atomic_flag_clear(atomic_flag* obj) noexcept;
890b57cec5SDimitry Andric
900b57cec5SDimitry Andricvoid
910b57cec5SDimitry Andric    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
920b57cec5SDimitry Andric
930b57cec5SDimitry Andricvoid
940b57cec5SDimitry Andric    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric#define ATOMIC_FLAG_INIT see below
970b57cec5SDimitry Andric#define ATOMIC_VAR_INIT(value) see below
980b57cec5SDimitry Andric
990b57cec5SDimitry Andrictemplate <class T>
1000b57cec5SDimitry Andricstruct atomic
1010b57cec5SDimitry Andric{
1020b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
1030b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
1040b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
1050b57cec5SDimitry Andric    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
1060b57cec5SDimitry Andric    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
1070b57cec5SDimitry Andric    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
1080b57cec5SDimitry Andric    T load(memory_order m = memory_order_seq_cst) const noexcept;
1090b57cec5SDimitry Andric    operator T() const volatile noexcept;
1100b57cec5SDimitry Andric    operator T() const noexcept;
1110b57cec5SDimitry Andric    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
1120b57cec5SDimitry Andric    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
1130b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
1140b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
1150b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
1160b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
1170b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
1180b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
1190b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
1200b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
1210b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
1220b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
1230b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
1240b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
1250b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
1260b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
1270b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
1280b57cec5SDimitry Andric
1290b57cec5SDimitry Andric    atomic() noexcept = default;
1300b57cec5SDimitry Andric    constexpr atomic(T desr) noexcept;
1310b57cec5SDimitry Andric    atomic(const atomic&) = delete;
1320b57cec5SDimitry Andric    atomic& operator=(const atomic&) = delete;
1330b57cec5SDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
1340b57cec5SDimitry Andric    T operator=(T) volatile noexcept;
1350b57cec5SDimitry Andric    T operator=(T) noexcept;
1360b57cec5SDimitry Andric};
1370b57cec5SDimitry Andric
1380b57cec5SDimitry Andrictemplate <>
1390b57cec5SDimitry Andricstruct atomic<integral>
1400b57cec5SDimitry Andric{
1410b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
1420b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
1430b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
1440b57cec5SDimitry Andric    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
1450b57cec5SDimitry Andric    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1460b57cec5SDimitry Andric    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
1470b57cec5SDimitry Andric    integral load(memory_order m = memory_order_seq_cst) const noexcept;
1480b57cec5SDimitry Andric    operator integral() const volatile noexcept;
1490b57cec5SDimitry Andric    operator integral() const noexcept;
1500b57cec5SDimitry Andric    integral exchange(integral desr,
1510b57cec5SDimitry Andric                      memory_order m = memory_order_seq_cst) volatile noexcept;
1520b57cec5SDimitry Andric    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1530b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1540b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
1550b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1560b57cec5SDimitry Andric                               memory_order s, memory_order f) noexcept;
1570b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1580b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
1590b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1600b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
1610b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1620b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
1630b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1640b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
1650b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1660b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
1670b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1680b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
1690b57cec5SDimitry Andric
1700b57cec5SDimitry Andric    integral
1710b57cec5SDimitry Andric        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1720b57cec5SDimitry Andric    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
1730b57cec5SDimitry Andric    integral
1740b57cec5SDimitry Andric        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1750b57cec5SDimitry Andric    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
1760b57cec5SDimitry Andric    integral
1770b57cec5SDimitry Andric        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1780b57cec5SDimitry Andric    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
1790b57cec5SDimitry Andric    integral
1800b57cec5SDimitry Andric        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1810b57cec5SDimitry Andric    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
1820b57cec5SDimitry Andric    integral
1830b57cec5SDimitry Andric        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1840b57cec5SDimitry Andric    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
1850b57cec5SDimitry Andric
1860b57cec5SDimitry Andric    atomic() noexcept = default;
1870b57cec5SDimitry Andric    constexpr atomic(integral desr) noexcept;
1880b57cec5SDimitry Andric    atomic(const atomic&) = delete;
1890b57cec5SDimitry Andric    atomic& operator=(const atomic&) = delete;
1900b57cec5SDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
1910b57cec5SDimitry Andric    integral operator=(integral desr) volatile noexcept;
1920b57cec5SDimitry Andric    integral operator=(integral desr) noexcept;
1930b57cec5SDimitry Andric
1940b57cec5SDimitry Andric    integral operator++(int) volatile noexcept;
1950b57cec5SDimitry Andric    integral operator++(int) noexcept;
1960b57cec5SDimitry Andric    integral operator--(int) volatile noexcept;
1970b57cec5SDimitry Andric    integral operator--(int) noexcept;
1980b57cec5SDimitry Andric    integral operator++() volatile noexcept;
1990b57cec5SDimitry Andric    integral operator++() noexcept;
2000b57cec5SDimitry Andric    integral operator--() volatile noexcept;
2010b57cec5SDimitry Andric    integral operator--() noexcept;
2020b57cec5SDimitry Andric    integral operator+=(integral op) volatile noexcept;
2030b57cec5SDimitry Andric    integral operator+=(integral op) noexcept;
2040b57cec5SDimitry Andric    integral operator-=(integral op) volatile noexcept;
2050b57cec5SDimitry Andric    integral operator-=(integral op) noexcept;
2060b57cec5SDimitry Andric    integral operator&=(integral op) volatile noexcept;
2070b57cec5SDimitry Andric    integral operator&=(integral op) noexcept;
2080b57cec5SDimitry Andric    integral operator|=(integral op) volatile noexcept;
2090b57cec5SDimitry Andric    integral operator|=(integral op) noexcept;
2100b57cec5SDimitry Andric    integral operator^=(integral op) volatile noexcept;
2110b57cec5SDimitry Andric    integral operator^=(integral op) noexcept;
2120b57cec5SDimitry Andric};
2130b57cec5SDimitry Andric
2140b57cec5SDimitry Andrictemplate <class T>
2150b57cec5SDimitry Andricstruct atomic<T*>
2160b57cec5SDimitry Andric{
2170b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
2180b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
2190b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
2200b57cec5SDimitry Andric    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
2210b57cec5SDimitry Andric    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2220b57cec5SDimitry Andric    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
2230b57cec5SDimitry Andric    T* load(memory_order m = memory_order_seq_cst) const noexcept;
2240b57cec5SDimitry Andric    operator T*() const volatile noexcept;
2250b57cec5SDimitry Andric    operator T*() const noexcept;
2260b57cec5SDimitry Andric    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
2270b57cec5SDimitry Andric    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2280b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2290b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
2300b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2310b57cec5SDimitry Andric                               memory_order s, memory_order f) noexcept;
2320b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2330b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
2340b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2350b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
2360b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2370b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
2380b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2390b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
2400b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2410b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
2420b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2430b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
2440b57cec5SDimitry Andric    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
2450b57cec5SDimitry Andric    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2460b57cec5SDimitry Andric    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
2470b57cec5SDimitry Andric    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2480b57cec5SDimitry Andric
2490b57cec5SDimitry Andric    atomic() noexcept = default;
2500b57cec5SDimitry Andric    constexpr atomic(T* desr) noexcept;
2510b57cec5SDimitry Andric    atomic(const atomic&) = delete;
2520b57cec5SDimitry Andric    atomic& operator=(const atomic&) = delete;
2530b57cec5SDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
2540b57cec5SDimitry Andric
2550b57cec5SDimitry Andric    T* operator=(T*) volatile noexcept;
2560b57cec5SDimitry Andric    T* operator=(T*) noexcept;
2570b57cec5SDimitry Andric    T* operator++(int) volatile noexcept;
2580b57cec5SDimitry Andric    T* operator++(int) noexcept;
2590b57cec5SDimitry Andric    T* operator--(int) volatile noexcept;
2600b57cec5SDimitry Andric    T* operator--(int) noexcept;
2610b57cec5SDimitry Andric    T* operator++() volatile noexcept;
2620b57cec5SDimitry Andric    T* operator++() noexcept;
2630b57cec5SDimitry Andric    T* operator--() volatile noexcept;
2640b57cec5SDimitry Andric    T* operator--() noexcept;
2650b57cec5SDimitry Andric    T* operator+=(ptrdiff_t op) volatile noexcept;
2660b57cec5SDimitry Andric    T* operator+=(ptrdiff_t op) noexcept;
2670b57cec5SDimitry Andric    T* operator-=(ptrdiff_t op) volatile noexcept;
2680b57cec5SDimitry Andric    T* operator-=(ptrdiff_t op) noexcept;
2690b57cec5SDimitry Andric};
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric
2720b57cec5SDimitry Andrictemplate <class T>
2730b57cec5SDimitry Andric    bool
2740b57cec5SDimitry Andric    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
2750b57cec5SDimitry Andric
2760b57cec5SDimitry Andrictemplate <class T>
2770b57cec5SDimitry Andric    bool
2780b57cec5SDimitry Andric    atomic_is_lock_free(const atomic<T>* obj) noexcept;
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andrictemplate <class T>
2810b57cec5SDimitry Andric    void
2820b57cec5SDimitry Andric    atomic_init(volatile atomic<T>* obj, T desr) noexcept;
2830b57cec5SDimitry Andric
2840b57cec5SDimitry Andrictemplate <class T>
2850b57cec5SDimitry Andric    void
2860b57cec5SDimitry Andric    atomic_init(atomic<T>* obj, T desr) noexcept;
2870b57cec5SDimitry Andric
2880b57cec5SDimitry Andrictemplate <class T>
2890b57cec5SDimitry Andric    void
2900b57cec5SDimitry Andric    atomic_store(volatile atomic<T>* obj, T desr) noexcept;
2910b57cec5SDimitry Andric
2920b57cec5SDimitry Andrictemplate <class T>
2930b57cec5SDimitry Andric    void
2940b57cec5SDimitry Andric    atomic_store(atomic<T>* obj, T desr) noexcept;
2950b57cec5SDimitry Andric
2960b57cec5SDimitry Andrictemplate <class T>
2970b57cec5SDimitry Andric    void
2980b57cec5SDimitry Andric    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
2990b57cec5SDimitry Andric
3000b57cec5SDimitry Andrictemplate <class T>
3010b57cec5SDimitry Andric    void
3020b57cec5SDimitry Andric    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
3030b57cec5SDimitry Andric
3040b57cec5SDimitry Andrictemplate <class T>
3050b57cec5SDimitry Andric    T
3060b57cec5SDimitry Andric    atomic_load(const volatile atomic<T>* obj) noexcept;
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andrictemplate <class T>
3090b57cec5SDimitry Andric    T
3100b57cec5SDimitry Andric    atomic_load(const atomic<T>* obj) noexcept;
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andrictemplate <class T>
3130b57cec5SDimitry Andric    T
3140b57cec5SDimitry Andric    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andrictemplate <class T>
3170b57cec5SDimitry Andric    T
3180b57cec5SDimitry Andric    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andrictemplate <class T>
3210b57cec5SDimitry Andric    T
3220b57cec5SDimitry Andric    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andrictemplate <class T>
3250b57cec5SDimitry Andric    T
3260b57cec5SDimitry Andric    atomic_exchange(atomic<T>* obj, T desr) noexcept;
3270b57cec5SDimitry Andric
3280b57cec5SDimitry Andrictemplate <class T>
3290b57cec5SDimitry Andric    T
3300b57cec5SDimitry Andric    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
3310b57cec5SDimitry Andric
3320b57cec5SDimitry Andrictemplate <class T>
3330b57cec5SDimitry Andric    T
3340b57cec5SDimitry Andric    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
3350b57cec5SDimitry Andric
3360b57cec5SDimitry Andrictemplate <class T>
3370b57cec5SDimitry Andric    bool
3380b57cec5SDimitry Andric    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
3390b57cec5SDimitry Andric
3400b57cec5SDimitry Andrictemplate <class T>
3410b57cec5SDimitry Andric    bool
3420b57cec5SDimitry Andric    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
3430b57cec5SDimitry Andric
3440b57cec5SDimitry Andrictemplate <class T>
3450b57cec5SDimitry Andric    bool
3460b57cec5SDimitry Andric    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andrictemplate <class T>
3490b57cec5SDimitry Andric    bool
3500b57cec5SDimitry Andric    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andrictemplate <class T>
3530b57cec5SDimitry Andric    bool
3540b57cec5SDimitry Andric    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
3550b57cec5SDimitry Andric                                          T desr,
3560b57cec5SDimitry Andric                                          memory_order s, memory_order f) noexcept;
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andrictemplate <class T>
3590b57cec5SDimitry Andric    bool
3600b57cec5SDimitry Andric    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
3610b57cec5SDimitry Andric                                          memory_order s, memory_order f) noexcept;
3620b57cec5SDimitry Andric
3630b57cec5SDimitry Andrictemplate <class T>
3640b57cec5SDimitry Andric    bool
3650b57cec5SDimitry Andric    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
3660b57cec5SDimitry Andric                                            T* expc, T desr,
3670b57cec5SDimitry Andric                                            memory_order s, memory_order f) noexcept;
3680b57cec5SDimitry Andric
3690b57cec5SDimitry Andrictemplate <class T>
3700b57cec5SDimitry Andric    bool
3710b57cec5SDimitry Andric    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
3720b57cec5SDimitry Andric                                            T desr,
3730b57cec5SDimitry Andric                                            memory_order s, memory_order f) noexcept;
3740b57cec5SDimitry Andric
3750b57cec5SDimitry Andrictemplate <class Integral>
3760b57cec5SDimitry Andric    Integral
3770b57cec5SDimitry Andric    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
3780b57cec5SDimitry Andric
3790b57cec5SDimitry Andrictemplate <class Integral>
3800b57cec5SDimitry Andric    Integral
3810b57cec5SDimitry Andric    atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
3820b57cec5SDimitry Andric
3830b57cec5SDimitry Andrictemplate <class Integral>
3840b57cec5SDimitry Andric    Integral
3850b57cec5SDimitry Andric    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
3860b57cec5SDimitry Andric                              memory_order m) noexcept;
3870b57cec5SDimitry Andrictemplate <class Integral>
3880b57cec5SDimitry Andric    Integral
3890b57cec5SDimitry Andric    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
3900b57cec5SDimitry Andric                              memory_order m) noexcept;
3910b57cec5SDimitry Andrictemplate <class Integral>
3920b57cec5SDimitry Andric    Integral
3930b57cec5SDimitry Andric    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andrictemplate <class Integral>
3960b57cec5SDimitry Andric    Integral
3970b57cec5SDimitry Andric    atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andrictemplate <class Integral>
4000b57cec5SDimitry Andric    Integral
4010b57cec5SDimitry Andric    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
4020b57cec5SDimitry Andric                              memory_order m) noexcept;
4030b57cec5SDimitry Andrictemplate <class Integral>
4040b57cec5SDimitry Andric    Integral
4050b57cec5SDimitry Andric    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
4060b57cec5SDimitry Andric                              memory_order m) noexcept;
4070b57cec5SDimitry Andrictemplate <class Integral>
4080b57cec5SDimitry Andric    Integral
4090b57cec5SDimitry Andric    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andrictemplate <class Integral>
4120b57cec5SDimitry Andric    Integral
4130b57cec5SDimitry Andric    atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andrictemplate <class Integral>
4160b57cec5SDimitry Andric    Integral
4170b57cec5SDimitry Andric    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
4180b57cec5SDimitry Andric                              memory_order m) noexcept;
4190b57cec5SDimitry Andrictemplate <class Integral>
4200b57cec5SDimitry Andric    Integral
4210b57cec5SDimitry Andric    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
4220b57cec5SDimitry Andric                              memory_order m) noexcept;
4230b57cec5SDimitry Andrictemplate <class Integral>
4240b57cec5SDimitry Andric    Integral
4250b57cec5SDimitry Andric    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
4260b57cec5SDimitry Andric
4270b57cec5SDimitry Andrictemplate <class Integral>
4280b57cec5SDimitry Andric    Integral
4290b57cec5SDimitry Andric    atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
4300b57cec5SDimitry Andric
4310b57cec5SDimitry Andrictemplate <class Integral>
4320b57cec5SDimitry Andric    Integral
4330b57cec5SDimitry Andric    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
4340b57cec5SDimitry Andric                             memory_order m) noexcept;
4350b57cec5SDimitry Andrictemplate <class Integral>
4360b57cec5SDimitry Andric    Integral
4370b57cec5SDimitry Andric    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
4380b57cec5SDimitry Andric                             memory_order m) noexcept;
4390b57cec5SDimitry Andrictemplate <class Integral>
4400b57cec5SDimitry Andric    Integral
4410b57cec5SDimitry Andric    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
4420b57cec5SDimitry Andric
4430b57cec5SDimitry Andrictemplate <class Integral>
4440b57cec5SDimitry Andric    Integral
4450b57cec5SDimitry Andric    atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
4460b57cec5SDimitry Andric
4470b57cec5SDimitry Andrictemplate <class Integral>
4480b57cec5SDimitry Andric    Integral
4490b57cec5SDimitry Andric    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
4500b57cec5SDimitry Andric                              memory_order m) noexcept;
4510b57cec5SDimitry Andrictemplate <class Integral>
4520b57cec5SDimitry Andric    Integral
4530b57cec5SDimitry Andric    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
4540b57cec5SDimitry Andric                              memory_order m) noexcept;
4550b57cec5SDimitry Andric
4560b57cec5SDimitry Andrictemplate <class T>
4570b57cec5SDimitry Andric    T*
4580b57cec5SDimitry Andric    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
4590b57cec5SDimitry Andric
4600b57cec5SDimitry Andrictemplate <class T>
4610b57cec5SDimitry Andric    T*
4620b57cec5SDimitry Andric    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
4630b57cec5SDimitry Andric
4640b57cec5SDimitry Andrictemplate <class T>
4650b57cec5SDimitry Andric    T*
4660b57cec5SDimitry Andric    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
4670b57cec5SDimitry Andric                              memory_order m) noexcept;
4680b57cec5SDimitry Andrictemplate <class T>
4690b57cec5SDimitry Andric    T*
4700b57cec5SDimitry Andric    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
4710b57cec5SDimitry Andric
4720b57cec5SDimitry Andrictemplate <class T>
4730b57cec5SDimitry Andric    T*
4740b57cec5SDimitry Andric    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andrictemplate <class T>
4770b57cec5SDimitry Andric    T*
4780b57cec5SDimitry Andric    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
4790b57cec5SDimitry Andric
4800b57cec5SDimitry Andrictemplate <class T>
4810b57cec5SDimitry Andric    T*
4820b57cec5SDimitry Andric    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
4830b57cec5SDimitry Andric                              memory_order m) noexcept;
4840b57cec5SDimitry Andrictemplate <class T>
4850b57cec5SDimitry Andric    T*
4860b57cec5SDimitry Andric    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
4870b57cec5SDimitry Andric
4880b57cec5SDimitry Andric// Atomics for standard typedef types
4890b57cec5SDimitry Andric
4900b57cec5SDimitry Andrictypedef atomic<bool>               atomic_bool;
4910b57cec5SDimitry Andrictypedef atomic<char>               atomic_char;
4920b57cec5SDimitry Andrictypedef atomic<signed char>        atomic_schar;
4930b57cec5SDimitry Andrictypedef atomic<unsigned char>      atomic_uchar;
4940b57cec5SDimitry Andrictypedef atomic<short>              atomic_short;
4950b57cec5SDimitry Andrictypedef atomic<unsigned short>     atomic_ushort;
4960b57cec5SDimitry Andrictypedef atomic<int>                atomic_int;
4970b57cec5SDimitry Andrictypedef atomic<unsigned int>       atomic_uint;
4980b57cec5SDimitry Andrictypedef atomic<long>               atomic_long;
4990b57cec5SDimitry Andrictypedef atomic<unsigned long>      atomic_ulong;
5000b57cec5SDimitry Andrictypedef atomic<long long>          atomic_llong;
5010b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong;
5020b57cec5SDimitry Andrictypedef atomic<char16_t>           atomic_char16_t;
5030b57cec5SDimitry Andrictypedef atomic<char32_t>           atomic_char32_t;
5040b57cec5SDimitry Andrictypedef atomic<wchar_t>            atomic_wchar_t;
5050b57cec5SDimitry Andric
5060b57cec5SDimitry Andrictypedef atomic<int_least8_t>   atomic_int_least8_t;
5070b57cec5SDimitry Andrictypedef atomic<uint_least8_t>  atomic_uint_least8_t;
5080b57cec5SDimitry Andrictypedef atomic<int_least16_t>  atomic_int_least16_t;
5090b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t;
5100b57cec5SDimitry Andrictypedef atomic<int_least32_t>  atomic_int_least32_t;
5110b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t;
5120b57cec5SDimitry Andrictypedef atomic<int_least64_t>  atomic_int_least64_t;
5130b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t;
5140b57cec5SDimitry Andric
5150b57cec5SDimitry Andrictypedef atomic<int_fast8_t>   atomic_int_fast8_t;
5160b57cec5SDimitry Andrictypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
5170b57cec5SDimitry Andrictypedef atomic<int_fast16_t>  atomic_int_fast16_t;
5180b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
5190b57cec5SDimitry Andrictypedef atomic<int_fast32_t>  atomic_int_fast32_t;
5200b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
5210b57cec5SDimitry Andrictypedef atomic<int_fast64_t>  atomic_int_fast64_t;
5220b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andrictypedef atomic<int8_t>   atomic_int8_t;
5250b57cec5SDimitry Andrictypedef atomic<uint8_t>  atomic_uint8_t;
5260b57cec5SDimitry Andrictypedef atomic<int16_t>  atomic_int16_t;
5270b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t;
5280b57cec5SDimitry Andrictypedef atomic<int32_t>  atomic_int32_t;
5290b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t;
5300b57cec5SDimitry Andrictypedef atomic<int64_t>  atomic_int64_t;
5310b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t;
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andrictypedef atomic<intptr_t>  atomic_intptr_t;
5340b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t;
5350b57cec5SDimitry Andrictypedef atomic<size_t>    atomic_size_t;
5360b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
5370b57cec5SDimitry Andrictypedef atomic<intmax_t>  atomic_intmax_t;
5380b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t;
5390b57cec5SDimitry Andric
5400b57cec5SDimitry Andric// fences
5410b57cec5SDimitry Andric
5420b57cec5SDimitry Andricvoid atomic_thread_fence(memory_order m) noexcept;
5430b57cec5SDimitry Andricvoid atomic_signal_fence(memory_order m) noexcept;
5440b57cec5SDimitry Andric
5450b57cec5SDimitry Andric}  // std
5460b57cec5SDimitry Andric
5470b57cec5SDimitry Andric*/
5480b57cec5SDimitry Andric
5490b57cec5SDimitry Andric#include <__config>
5500b57cec5SDimitry Andric#include <cstddef>
5510b57cec5SDimitry Andric#include <cstdint>
5520b57cec5SDimitry Andric#include <type_traits>
5530b57cec5SDimitry Andric#include <version>
5540b57cec5SDimitry Andric
5550b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
5560b57cec5SDimitry Andric#pragma GCC system_header
5570b57cec5SDimitry Andric#endif
5580b57cec5SDimitry Andric
5590b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_THREADS
5600b57cec5SDimitry Andric# error <atomic> is not supported on this single threaded system
5610b57cec5SDimitry Andric#endif
5620b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
5630b57cec5SDimitry Andric# error <atomic> is not implemented
5640b57cec5SDimitry Andric#endif
5650b57cec5SDimitry Andric#ifdef kill_dependency
5660b57cec5SDimitry Andric# error C++ standard library is incompatible with <stdatomic.h>
5670b57cec5SDimitry Andric#endif
5680b57cec5SDimitry Andric
5690b57cec5SDimitry Andric#define _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) \
5700b57cec5SDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_consume || \
5710b57cec5SDimitry Andric                           __m == memory_order_acquire || \
5720b57cec5SDimitry Andric                           __m == memory_order_acq_rel,   \
5730b57cec5SDimitry Andric                        "memory order argument to atomic operation is invalid")
5740b57cec5SDimitry Andric
5750b57cec5SDimitry Andric#define _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) \
5760b57cec5SDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || \
5770b57cec5SDimitry Andric                           __m == memory_order_acq_rel,   \
5780b57cec5SDimitry Andric                        "memory order argument to atomic operation is invalid")
5790b57cec5SDimitry Andric
5800b57cec5SDimitry Andric#define _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__m, __f) \
5810b57cec5SDimitry Andric  _LIBCPP_DIAGNOSE_WARNING(__f == memory_order_release || \
5820b57cec5SDimitry Andric                           __f == memory_order_acq_rel,   \
5830b57cec5SDimitry Andric                        "memory order argument to atomic operation is invalid")
5840b57cec5SDimitry Andric
5850b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
5860b57cec5SDimitry Andric
5870b57cec5SDimitry Andric// Figure out what the underlying type for `memory_order` would be if it were
5880b57cec5SDimitry Andric// declared as an unscoped enum (accounting for -fshort-enums). Use this result
5890b57cec5SDimitry Andric// to pin the underlying type in C++20.
5900b57cec5SDimitry Andricenum __legacy_memory_order {
5910b57cec5SDimitry Andric    __mo_relaxed,
5920b57cec5SDimitry Andric    __mo_consume,
5930b57cec5SDimitry Andric    __mo_acquire,
5940b57cec5SDimitry Andric    __mo_release,
5950b57cec5SDimitry Andric    __mo_acq_rel,
5960b57cec5SDimitry Andric    __mo_seq_cst
5970b57cec5SDimitry Andric};
5980b57cec5SDimitry Andric
5990b57cec5SDimitry Andrictypedef underlying_type<__legacy_memory_order>::type __memory_order_underlying_t;
6000b57cec5SDimitry Andric
6010b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andricenum class memory_order : __memory_order_underlying_t {
6040b57cec5SDimitry Andric  relaxed = __mo_relaxed,
6050b57cec5SDimitry Andric  consume = __mo_consume,
6060b57cec5SDimitry Andric  acquire = __mo_acquire,
6070b57cec5SDimitry Andric  release = __mo_release,
6080b57cec5SDimitry Andric  acq_rel = __mo_acq_rel,
6090b57cec5SDimitry Andric  seq_cst = __mo_seq_cst
6100b57cec5SDimitry Andric};
6110b57cec5SDimitry Andric
6120b57cec5SDimitry Andricinline constexpr auto memory_order_relaxed = memory_order::relaxed;
6130b57cec5SDimitry Andricinline constexpr auto memory_order_consume = memory_order::consume;
6140b57cec5SDimitry Andricinline constexpr auto memory_order_acquire = memory_order::acquire;
6150b57cec5SDimitry Andricinline constexpr auto memory_order_release = memory_order::release;
6160b57cec5SDimitry Andricinline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
6170b57cec5SDimitry Andricinline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
6180b57cec5SDimitry Andric
6190b57cec5SDimitry Andric#else
6200b57cec5SDimitry Andric
6210b57cec5SDimitry Andrictypedef enum memory_order {
6220b57cec5SDimitry Andric  memory_order_relaxed = __mo_relaxed,
6230b57cec5SDimitry Andric  memory_order_consume = __mo_consume,
6240b57cec5SDimitry Andric  memory_order_acquire = __mo_acquire,
6250b57cec5SDimitry Andric  memory_order_release = __mo_release,
6260b57cec5SDimitry Andric  memory_order_acq_rel = __mo_acq_rel,
6270b57cec5SDimitry Andric  memory_order_seq_cst = __mo_seq_cst,
6280b57cec5SDimitry Andric} memory_order;
6290b57cec5SDimitry Andric
6300b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 17
6310b57cec5SDimitry Andric
6320b57cec5SDimitry Andricstatic_assert((is_same<underlying_type<memory_order>::type, __memory_order_underlying_t>::value),
6330b57cec5SDimitry Andric  "unexpected underlying type for std::memory_order");
6340b57cec5SDimitry Andric
6350b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP) || \
6360b57cec5SDimitry Andric	defined(_LIBCPP_ATOMIC_ONLY_USE_BUILTINS)
6370b57cec5SDimitry Andric
6380b57cec5SDimitry Andric// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because
6390b57cec5SDimitry Andric// the default operator= in an object is not volatile, a byte-by-byte copy
6400b57cec5SDimitry Andric// is required.
6410b57cec5SDimitry Andrictemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
6420b57cec5SDimitry Andrictypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
6430b57cec5SDimitry Andric__cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) {
6440b57cec5SDimitry Andric  __a_value = __val;
6450b57cec5SDimitry Andric}
6460b57cec5SDimitry Andrictemplate <typename _Tp, typename _Tv> _LIBCPP_INLINE_VISIBILITY
6470b57cec5SDimitry Andrictypename enable_if<is_assignable<_Tp&, _Tv>::value>::type
6480b57cec5SDimitry Andric__cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) {
6490b57cec5SDimitry Andric  volatile char* __to = reinterpret_cast<volatile char*>(&__a_value);
6500b57cec5SDimitry Andric  volatile char* __end = __to + sizeof(_Tp);
6510b57cec5SDimitry Andric  volatile const char* __from = reinterpret_cast<volatile const char*>(&__val);
6520b57cec5SDimitry Andric  while (__to != __end)
6530b57cec5SDimitry Andric    *__to++ = *__from++;
6540b57cec5SDimitry Andric}
6550b57cec5SDimitry Andric
6560b57cec5SDimitry Andric#endif
6570b57cec5SDimitry Andric
6580b57cec5SDimitry Andric#if defined(_LIBCPP_HAS_GCC_ATOMIC_IMP)
6590b57cec5SDimitry Andric
6600b57cec5SDimitry Andrictemplate <typename _Tp>
6610b57cec5SDimitry Andricstruct __cxx_atomic_base_impl {
6620b57cec5SDimitry Andric
6630b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
6640b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
6650b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT = default;
6660b57cec5SDimitry Andric#else
6670b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
6680b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
6690b57cec5SDimitry Andric  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
6700b57cec5SDimitry Andric    : __a_value(value) {}
6710b57cec5SDimitry Andric  _Tp __a_value;
6720b57cec5SDimitry Andric};
6730b57cec5SDimitry Andric
6740b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_order(memory_order __order) {
6750b57cec5SDimitry Andric  // Avoid switch statement to make this a constexpr.
6760b57cec5SDimitry Andric  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
6770b57cec5SDimitry Andric         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
6780b57cec5SDimitry Andric          (__order == memory_order_release ? __ATOMIC_RELEASE:
6790b57cec5SDimitry Andric           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
6800b57cec5SDimitry Andric            (__order == memory_order_acq_rel ? __ATOMIC_ACQ_REL:
6810b57cec5SDimitry Andric              __ATOMIC_CONSUME))));
6820b57cec5SDimitry Andric}
6830b57cec5SDimitry Andric
6840b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory_order __order) {
6850b57cec5SDimitry Andric  // Avoid switch statement to make this a constexpr.
6860b57cec5SDimitry Andric  return __order == memory_order_relaxed ? __ATOMIC_RELAXED:
6870b57cec5SDimitry Andric         (__order == memory_order_acquire ? __ATOMIC_ACQUIRE:
6880b57cec5SDimitry Andric          (__order == memory_order_release ? __ATOMIC_RELAXED:
6890b57cec5SDimitry Andric           (__order == memory_order_seq_cst ? __ATOMIC_SEQ_CST:
6900b57cec5SDimitry Andric            (__order == memory_order_acq_rel ? __ATOMIC_ACQUIRE:
6910b57cec5SDimitry Andric              __ATOMIC_CONSUME))));
6920b57cec5SDimitry Andric}
6930b57cec5SDimitry Andric
6940b57cec5SDimitry Andrictemplate <typename _Tp>
6950b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
6960b57cec5SDimitry Andricvoid __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
6970b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __val);
6980b57cec5SDimitry Andric}
6990b57cec5SDimitry Andric
7000b57cec5SDimitry Andrictemplate <typename _Tp>
7010b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7020b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val) {
7030b57cec5SDimitry Andric  __a->__a_value = __val;
7040b57cec5SDimitry Andric}
7050b57cec5SDimitry Andric
7060b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
7070b57cec5SDimitry Andricvoid __cxx_atomic_thread_fence(memory_order __order) {
7080b57cec5SDimitry Andric  __atomic_thread_fence(__to_gcc_order(__order));
7090b57cec5SDimitry Andric}
7100b57cec5SDimitry Andric
7110b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
7120b57cec5SDimitry Andricvoid __cxx_atomic_signal_fence(memory_order __order) {
7130b57cec5SDimitry Andric  __atomic_signal_fence(__to_gcc_order(__order));
7140b57cec5SDimitry Andric}
7150b57cec5SDimitry Andric
7160b57cec5SDimitry Andrictemplate <typename _Tp>
7170b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7180b57cec5SDimitry Andricvoid __cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
7190b57cec5SDimitry Andric                        memory_order __order) {
7200b57cec5SDimitry Andric  __atomic_store(&__a->__a_value, &__val,
7210b57cec5SDimitry Andric                 __to_gcc_order(__order));
7220b57cec5SDimitry Andric}
7230b57cec5SDimitry Andric
7240b57cec5SDimitry Andrictemplate <typename _Tp>
7250b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7260b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a,  _Tp __val,
7270b57cec5SDimitry Andric                        memory_order __order) {
7280b57cec5SDimitry Andric  __atomic_store(&__a->__a_value, &__val,
7290b57cec5SDimitry Andric                 __to_gcc_order(__order));
7300b57cec5SDimitry Andric}
7310b57cec5SDimitry Andric
7320b57cec5SDimitry Andrictemplate <typename _Tp>
7330b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7340b57cec5SDimitry Andric_Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a,
7350b57cec5SDimitry Andric                      memory_order __order) {
7360b57cec5SDimitry Andric  _Tp __ret;
7370b57cec5SDimitry Andric  __atomic_load(&__a->__a_value, &__ret,
7380b57cec5SDimitry Andric                __to_gcc_order(__order));
7390b57cec5SDimitry Andric  return __ret;
7400b57cec5SDimitry Andric}
7410b57cec5SDimitry Andric
7420b57cec5SDimitry Andrictemplate <typename _Tp>
7430b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7440b57cec5SDimitry Andric_Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) {
7450b57cec5SDimitry Andric  _Tp __ret;
7460b57cec5SDimitry Andric  __atomic_load(&__a->__a_value, &__ret,
7470b57cec5SDimitry Andric                __to_gcc_order(__order));
7480b57cec5SDimitry Andric  return __ret;
7490b57cec5SDimitry Andric}
7500b57cec5SDimitry Andric
7510b57cec5SDimitry Andrictemplate <typename _Tp>
7520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7530b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a,
7540b57cec5SDimitry Andric                          _Tp __value, memory_order __order) {
7550b57cec5SDimitry Andric  _Tp __ret;
7560b57cec5SDimitry Andric  __atomic_exchange(&__a->__a_value, &__value, &__ret,
7570b57cec5SDimitry Andric                    __to_gcc_order(__order));
7580b57cec5SDimitry Andric  return __ret;
7590b57cec5SDimitry Andric}
7600b57cec5SDimitry Andric
7610b57cec5SDimitry Andrictemplate <typename _Tp>
7620b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7630b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value,
7640b57cec5SDimitry Andric                          memory_order __order) {
7650b57cec5SDimitry Andric  _Tp __ret;
7660b57cec5SDimitry Andric  __atomic_exchange(&__a->__a_value, &__value, &__ret,
7670b57cec5SDimitry Andric                    __to_gcc_order(__order));
7680b57cec5SDimitry Andric  return __ret;
7690b57cec5SDimitry Andric}
7700b57cec5SDimitry Andric
7710b57cec5SDimitry Andrictemplate <typename _Tp>
7720b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7730b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(
7740b57cec5SDimitry Andric    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
7750b57cec5SDimitry Andric    memory_order __success, memory_order __failure) {
7760b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
7770b57cec5SDimitry Andric                                   false,
7780b57cec5SDimitry Andric                                   __to_gcc_order(__success),
7790b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
7800b57cec5SDimitry Andric}
7810b57cec5SDimitry Andric
7820b57cec5SDimitry Andrictemplate <typename _Tp>
7830b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7840b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(
7850b57cec5SDimitry Andric    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
7860b57cec5SDimitry Andric    memory_order __failure) {
7870b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
7880b57cec5SDimitry Andric                                   false,
7890b57cec5SDimitry Andric                                   __to_gcc_order(__success),
7900b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
7910b57cec5SDimitry Andric}
7920b57cec5SDimitry Andric
7930b57cec5SDimitry Andrictemplate <typename _Tp>
7940b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
7950b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(
7960b57cec5SDimitry Andric    volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value,
7970b57cec5SDimitry Andric    memory_order __success, memory_order __failure) {
7980b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
7990b57cec5SDimitry Andric                                   true,
8000b57cec5SDimitry Andric                                   __to_gcc_order(__success),
8010b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
8020b57cec5SDimitry Andric}
8030b57cec5SDimitry Andric
8040b57cec5SDimitry Andrictemplate <typename _Tp>
8050b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8060b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(
8070b57cec5SDimitry Andric    __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success,
8080b57cec5SDimitry Andric    memory_order __failure) {
8090b57cec5SDimitry Andric  return __atomic_compare_exchange(&__a->__a_value, __expected, &__value,
8100b57cec5SDimitry Andric                                   true,
8110b57cec5SDimitry Andric                                   __to_gcc_order(__success),
8120b57cec5SDimitry Andric                                   __to_gcc_failure_order(__failure));
8130b57cec5SDimitry Andric}
8140b57cec5SDimitry Andric
8150b57cec5SDimitry Andrictemplate <typename _Tp>
8160b57cec5SDimitry Andricstruct __skip_amt { enum {value = 1}; };
8170b57cec5SDimitry Andric
8180b57cec5SDimitry Andrictemplate <typename _Tp>
8190b57cec5SDimitry Andricstruct __skip_amt<_Tp*> { enum {value = sizeof(_Tp)}; };
8200b57cec5SDimitry Andric
8210b57cec5SDimitry Andric// FIXME: Haven't figured out what the spec says about using arrays with
8220b57cec5SDimitry Andric// atomic_fetch_add. Force a failure rather than creating bad behavior.
8230b57cec5SDimitry Andrictemplate <typename _Tp>
8240b57cec5SDimitry Andricstruct __skip_amt<_Tp[]> { };
8250b57cec5SDimitry Andrictemplate <typename _Tp, int n>
8260b57cec5SDimitry Andricstruct __skip_amt<_Tp[n]> { };
8270b57cec5SDimitry Andric
8280b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
8290b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8300b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a,
8310b57cec5SDimitry Andric                           _Td __delta, memory_order __order) {
8320b57cec5SDimitry Andric  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8330b57cec5SDimitry Andric                            __to_gcc_order(__order));
8340b57cec5SDimitry Andric}
8350b57cec5SDimitry Andric
8360b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
8370b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8380b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
8390b57cec5SDimitry Andric                           memory_order __order) {
8400b57cec5SDimitry Andric  return __atomic_fetch_add(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8410b57cec5SDimitry Andric                            __to_gcc_order(__order));
8420b57cec5SDimitry Andric}
8430b57cec5SDimitry Andric
8440b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
8450b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8460b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a,
8470b57cec5SDimitry Andric                           _Td __delta, memory_order __order) {
8480b57cec5SDimitry Andric  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8490b57cec5SDimitry Andric                            __to_gcc_order(__order));
8500b57cec5SDimitry Andric}
8510b57cec5SDimitry Andric
8520b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
8530b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8540b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta,
8550b57cec5SDimitry Andric                           memory_order __order) {
8560b57cec5SDimitry Andric  return __atomic_fetch_sub(&__a->__a_value, __delta * __skip_amt<_Tp>::value,
8570b57cec5SDimitry Andric                            __to_gcc_order(__order));
8580b57cec5SDimitry Andric}
8590b57cec5SDimitry Andric
8600b57cec5SDimitry Andrictemplate <typename _Tp>
8610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8620b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a,
8630b57cec5SDimitry Andric                           _Tp __pattern, memory_order __order) {
8640b57cec5SDimitry Andric  return __atomic_fetch_and(&__a->__a_value, __pattern,
8650b57cec5SDimitry Andric                            __to_gcc_order(__order));
8660b57cec5SDimitry Andric}
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andrictemplate <typename _Tp>
8690b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8700b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a,
8710b57cec5SDimitry Andric                           _Tp __pattern, memory_order __order) {
8720b57cec5SDimitry Andric  return __atomic_fetch_and(&__a->__a_value, __pattern,
8730b57cec5SDimitry Andric                            __to_gcc_order(__order));
8740b57cec5SDimitry Andric}
8750b57cec5SDimitry Andric
8760b57cec5SDimitry Andrictemplate <typename _Tp>
8770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8780b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a,
8790b57cec5SDimitry Andric                          _Tp __pattern, memory_order __order) {
8800b57cec5SDimitry Andric  return __atomic_fetch_or(&__a->__a_value, __pattern,
8810b57cec5SDimitry Andric                           __to_gcc_order(__order));
8820b57cec5SDimitry Andric}
8830b57cec5SDimitry Andric
8840b57cec5SDimitry Andrictemplate <typename _Tp>
8850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8860b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
8870b57cec5SDimitry Andric                          memory_order __order) {
8880b57cec5SDimitry Andric  return __atomic_fetch_or(&__a->__a_value, __pattern,
8890b57cec5SDimitry Andric                           __to_gcc_order(__order));
8900b57cec5SDimitry Andric}
8910b57cec5SDimitry Andric
8920b57cec5SDimitry Andrictemplate <typename _Tp>
8930b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
8940b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a,
8950b57cec5SDimitry Andric                           _Tp __pattern, memory_order __order) {
8960b57cec5SDimitry Andric  return __atomic_fetch_xor(&__a->__a_value, __pattern,
8970b57cec5SDimitry Andric                            __to_gcc_order(__order));
8980b57cec5SDimitry Andric}
8990b57cec5SDimitry Andric
9000b57cec5SDimitry Andrictemplate <typename _Tp>
9010b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9020b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern,
9030b57cec5SDimitry Andric                           memory_order __order) {
9040b57cec5SDimitry Andric  return __atomic_fetch_xor(&__a->__a_value, __pattern,
9050b57cec5SDimitry Andric                            __to_gcc_order(__order));
9060b57cec5SDimitry Andric}
9070b57cec5SDimitry Andric
9080b57cec5SDimitry Andric#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0)
9090b57cec5SDimitry Andric
9100b57cec5SDimitry Andric#elif defined(_LIBCPP_HAS_C_ATOMIC_IMP)
9110b57cec5SDimitry Andric
9120b57cec5SDimitry Andrictemplate <typename _Tp>
9130b57cec5SDimitry Andricstruct __cxx_atomic_base_impl {
9140b57cec5SDimitry Andric
9150b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
9160b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
9170b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT = default;
9180b57cec5SDimitry Andric#else
9190b57cec5SDimitry Andric    __cxx_atomic_base_impl() _NOEXCEPT : __a_value() {}
9200b57cec5SDimitry Andric#endif // _LIBCPP_CXX03_LANG
9210b57cec5SDimitry Andric  _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT
9220b57cec5SDimitry Andric    : __a_value(value) {}
923*e40139ffSDimitry Andric  _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value;
9240b57cec5SDimitry Andric};
9250b57cec5SDimitry Andric
9260b57cec5SDimitry Andric#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s)
9270b57cec5SDimitry Andric
9280b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
9290b57cec5SDimitry Andricvoid __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT {
9300b57cec5SDimitry Andric    __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order));
9310b57cec5SDimitry Andric}
9320b57cec5SDimitry Andric
9330b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY inline
9340b57cec5SDimitry Andricvoid __cxx_atomic_signal_fence(memory_order __order) _NOEXCEPT {
9350b57cec5SDimitry Andric    __c11_atomic_signal_fence(static_cast<__memory_order_underlying_t>(__order));
9360b57cec5SDimitry Andric}
9370b57cec5SDimitry Andric
9380b57cec5SDimitry Andrictemplate<class _Tp>
9390b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9400b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val) _NOEXCEPT {
9410b57cec5SDimitry Andric    __c11_atomic_init(&__a->__a_value, __val);
9420b57cec5SDimitry Andric}
9430b57cec5SDimitry Andrictemplate<class _Tp>
9440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9450b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val) _NOEXCEPT {
9460b57cec5SDimitry Andric    __c11_atomic_init(&__a->__a_value, __val);
9470b57cec5SDimitry Andric}
9480b57cec5SDimitry Andric
9490b57cec5SDimitry Andrictemplate<class _Tp>
9500b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9510b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __val, memory_order __order) _NOEXCEPT {
9520b57cec5SDimitry Andric    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
9530b57cec5SDimitry Andric}
9540b57cec5SDimitry Andrictemplate<class _Tp>
9550b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9560b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_base_impl<_Tp> * __a, _Tp __val, memory_order __order) _NOEXCEPT {
9570b57cec5SDimitry Andric    __c11_atomic_store(&__a->__a_value, __val, static_cast<__memory_order_underlying_t>(__order));
9580b57cec5SDimitry Andric}
9590b57cec5SDimitry Andric
9600b57cec5SDimitry Andrictemplate<class _Tp>
9610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9620b57cec5SDimitry Andric_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const volatile* __a, memory_order __order) _NOEXCEPT {
9630b57cec5SDimitry Andric    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
9640b57cec5SDimitry Andric    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
9650b57cec5SDimitry Andric}
9660b57cec5SDimitry Andrictemplate<class _Tp>
9670b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9680b57cec5SDimitry Andric_Tp __cxx_atomic_load(__cxx_atomic_base_impl<_Tp> const* __a, memory_order __order) _NOEXCEPT {
9690b57cec5SDimitry Andric    using __ptr_type = typename remove_const<decltype(__a->__a_value)>::type*;
9700b57cec5SDimitry Andric    return __c11_atomic_load(const_cast<__ptr_type>(&__a->__a_value), static_cast<__memory_order_underlying_t>(__order));
9710b57cec5SDimitry Andric}
9720b57cec5SDimitry Andric
9730b57cec5SDimitry Andrictemplate<class _Tp>
9740b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9750b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __value, memory_order __order) _NOEXCEPT {
9760b57cec5SDimitry Andric    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
9770b57cec5SDimitry Andric}
9780b57cec5SDimitry Andrictemplate<class _Tp>
9790b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9800b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp> * __a, _Tp __value, memory_order __order) _NOEXCEPT {
9810b57cec5SDimitry Andric    return __c11_atomic_exchange(&__a->__a_value, __value, static_cast<__memory_order_underlying_t>(__order));
9820b57cec5SDimitry Andric}
9830b57cec5SDimitry Andric
9840b57cec5SDimitry Andrictemplate<class _Tp>
9850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9860b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9870b57cec5SDimitry Andric    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
9880b57cec5SDimitry Andric}
9890b57cec5SDimitry Andrictemplate<class _Tp>
9900b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9910b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9920b57cec5SDimitry Andric    return __c11_atomic_compare_exchange_strong(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
9930b57cec5SDimitry Andric}
9940b57cec5SDimitry Andric
9950b57cec5SDimitry Andrictemplate<class _Tp>
9960b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
9970b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
9980b57cec5SDimitry Andric    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value, static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
9990b57cec5SDimitry Andric}
10000b57cec5SDimitry Andrictemplate<class _Tp>
10010b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10020b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_base_impl<_Tp> * __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) _NOEXCEPT {
10030b57cec5SDimitry Andric    return __c11_atomic_compare_exchange_weak(&__a->__a_value, __expected, __value,  static_cast<__memory_order_underlying_t>(__success), static_cast<__memory_order_underlying_t>(__failure));
10040b57cec5SDimitry Andric}
10050b57cec5SDimitry Andric
10060b57cec5SDimitry Andrictemplate<class _Tp>
10070b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10080b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10090b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10100b57cec5SDimitry Andric}
10110b57cec5SDimitry Andrictemplate<class _Tp>
10120b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10130b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10140b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10150b57cec5SDimitry Andric}
10160b57cec5SDimitry Andric
10170b57cec5SDimitry Andrictemplate<class _Tp>
10180b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10190b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10200b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10210b57cec5SDimitry Andric}
10220b57cec5SDimitry Andrictemplate<class _Tp>
10230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10240b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10250b57cec5SDimitry Andric    return __c11_atomic_fetch_add(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10260b57cec5SDimitry Andric}
10270b57cec5SDimitry Andric
10280b57cec5SDimitry Andrictemplate<class _Tp>
10290b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10300b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10310b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10320b57cec5SDimitry Andric}
10330b57cec5SDimitry Andrictemplate<class _Tp>
10340b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10350b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp> * __a, _Tp __delta, memory_order __order) _NOEXCEPT {
10360b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10370b57cec5SDimitry Andric}
10380b57cec5SDimitry Andrictemplate<class _Tp>
10390b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10400b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10410b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10420b57cec5SDimitry Andric}
10430b57cec5SDimitry Andrictemplate<class _Tp>
10440b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10450b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp*> * __a, ptrdiff_t __delta, memory_order __order) _NOEXCEPT {
10460b57cec5SDimitry Andric    return __c11_atomic_fetch_sub(&__a->__a_value, __delta, static_cast<__memory_order_underlying_t>(__order));
10470b57cec5SDimitry Andric}
10480b57cec5SDimitry Andric
10490b57cec5SDimitry Andrictemplate<class _Tp>
10500b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10510b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10520b57cec5SDimitry Andric    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10530b57cec5SDimitry Andric}
10540b57cec5SDimitry Andrictemplate<class _Tp>
10550b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10560b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10570b57cec5SDimitry Andric    return __c11_atomic_fetch_and(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10580b57cec5SDimitry Andric}
10590b57cec5SDimitry Andric
10600b57cec5SDimitry Andrictemplate<class _Tp>
10610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10620b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10630b57cec5SDimitry Andric    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10640b57cec5SDimitry Andric}
10650b57cec5SDimitry Andrictemplate<class _Tp>
10660b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10670b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10680b57cec5SDimitry Andric    return __c11_atomic_fetch_or(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10690b57cec5SDimitry Andric}
10700b57cec5SDimitry Andric
10710b57cec5SDimitry Andrictemplate<class _Tp>
10720b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10730b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> volatile* __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10740b57cec5SDimitry Andric    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10750b57cec5SDimitry Andric}
10760b57cec5SDimitry Andrictemplate<class _Tp>
10770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10780b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp> * __a, _Tp __pattern, memory_order __order) _NOEXCEPT {
10790b57cec5SDimitry Andric    return __c11_atomic_fetch_xor(&__a->__a_value, __pattern, static_cast<__memory_order_underlying_t>(__order));
10800b57cec5SDimitry Andric}
10810b57cec5SDimitry Andric
10820b57cec5SDimitry Andric#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP
10830b57cec5SDimitry Andric
10840b57cec5SDimitry Andrictemplate <class _Tp>
10850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
10860b57cec5SDimitry Andric_Tp kill_dependency(_Tp __y) _NOEXCEPT
10870b57cec5SDimitry Andric{
10880b57cec5SDimitry Andric    return __y;
10890b57cec5SDimitry Andric}
10900b57cec5SDimitry Andric
10910b57cec5SDimitry Andric#if defined(__CLANG_ATOMIC_BOOL_LOCK_FREE)
10920b57cec5SDimitry Andric# define ATOMIC_BOOL_LOCK_FREE      __CLANG_ATOMIC_BOOL_LOCK_FREE
10930b57cec5SDimitry Andric# define ATOMIC_CHAR_LOCK_FREE      __CLANG_ATOMIC_CHAR_LOCK_FREE
10940b57cec5SDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE  __CLANG_ATOMIC_CHAR16_T_LOCK_FREE
10950b57cec5SDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE  __CLANG_ATOMIC_CHAR32_T_LOCK_FREE
10960b57cec5SDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE   __CLANG_ATOMIC_WCHAR_T_LOCK_FREE
10970b57cec5SDimitry Andric# define ATOMIC_SHORT_LOCK_FREE     __CLANG_ATOMIC_SHORT_LOCK_FREE
10980b57cec5SDimitry Andric# define ATOMIC_INT_LOCK_FREE       __CLANG_ATOMIC_INT_LOCK_FREE
10990b57cec5SDimitry Andric# define ATOMIC_LONG_LOCK_FREE      __CLANG_ATOMIC_LONG_LOCK_FREE
11000b57cec5SDimitry Andric# define ATOMIC_LLONG_LOCK_FREE     __CLANG_ATOMIC_LLONG_LOCK_FREE
11010b57cec5SDimitry Andric# define ATOMIC_POINTER_LOCK_FREE   __CLANG_ATOMIC_POINTER_LOCK_FREE
11020b57cec5SDimitry Andric#elif defined(__GCC_ATOMIC_BOOL_LOCK_FREE)
11030b57cec5SDimitry Andric# define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
11040b57cec5SDimitry Andric# define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
11050b57cec5SDimitry Andric# define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
11060b57cec5SDimitry Andric# define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
11070b57cec5SDimitry Andric# define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
11080b57cec5SDimitry Andric# define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
11090b57cec5SDimitry Andric# define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
11100b57cec5SDimitry Andric# define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
11110b57cec5SDimitry Andric# define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
11120b57cec5SDimitry Andric# define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
11130b57cec5SDimitry Andric#endif
11140b57cec5SDimitry Andric
11150b57cec5SDimitry Andric#ifdef _LIBCPP_ATOMIC_ONLY_USE_BUILTINS
11160b57cec5SDimitry Andric
11170b57cec5SDimitry Andrictemplate<typename _Tp>
11180b57cec5SDimitry Andricstruct __cxx_atomic_lock_impl {
11190b57cec5SDimitry Andric
11200b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY
11210b57cec5SDimitry Andric  __cxx_atomic_lock_impl() _NOEXCEPT
11220b57cec5SDimitry Andric    : __a_value(), __a_lock(0) {}
11230b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit
11240b57cec5SDimitry Andric  __cxx_atomic_lock_impl(_Tp value) _NOEXCEPT
11250b57cec5SDimitry Andric    : __a_value(value), __a_lock(0) {}
11260b57cec5SDimitry Andric
11270b57cec5SDimitry Andric  _Tp __a_value;
11280b57cec5SDimitry Andric  mutable __cxx_atomic_base_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_lock;
11290b57cec5SDimitry Andric
11300b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __lock() const volatile {
11310b57cec5SDimitry Andric    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
11320b57cec5SDimitry Andric        /*spin*/;
11330b57cec5SDimitry Andric  }
11340b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __lock() const {
11350b57cec5SDimitry Andric    while(1 == __cxx_atomic_exchange(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(true), memory_order_acquire))
11360b57cec5SDimitry Andric        /*spin*/;
11370b57cec5SDimitry Andric  }
11380b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __unlock() const volatile {
11390b57cec5SDimitry Andric    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
11400b57cec5SDimitry Andric  }
11410b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY void __unlock() const {
11420b57cec5SDimitry Andric    __cxx_atomic_store(&__a_lock, _LIBCPP_ATOMIC_FLAG_TYPE(false), memory_order_release);
11430b57cec5SDimitry Andric  }
11440b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _Tp __read() const volatile {
11450b57cec5SDimitry Andric    __lock();
11460b57cec5SDimitry Andric    _Tp __old;
11470b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(__old, __a_value);
11480b57cec5SDimitry Andric    __unlock();
11490b57cec5SDimitry Andric    return __old;
11500b57cec5SDimitry Andric  }
11510b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _Tp __read() const {
11520b57cec5SDimitry Andric    __lock();
11530b57cec5SDimitry Andric    _Tp __old = __a_value;
11540b57cec5SDimitry Andric    __unlock();
11550b57cec5SDimitry Andric    return __old;
11560b57cec5SDimitry Andric  }
11570b57cec5SDimitry Andric};
11580b57cec5SDimitry Andric
11590b57cec5SDimitry Andrictemplate <typename _Tp>
11600b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11610b57cec5SDimitry Andricvoid __cxx_atomic_init(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
11620b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __val);
11630b57cec5SDimitry Andric}
11640b57cec5SDimitry Andrictemplate <typename _Tp>
11650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11660b57cec5SDimitry Andricvoid __cxx_atomic_init(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val) {
11670b57cec5SDimitry Andric  __a->__a_value = __val;
11680b57cec5SDimitry Andric}
11690b57cec5SDimitry Andric
11700b57cec5SDimitry Andrictemplate <typename _Tp>
11710b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11720b57cec5SDimitry Andricvoid __cxx_atomic_store(volatile __cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
11730b57cec5SDimitry Andric  __a->__lock();
11740b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __val);
11750b57cec5SDimitry Andric  __a->__unlock();
11760b57cec5SDimitry Andric}
11770b57cec5SDimitry Andrictemplate <typename _Tp>
11780b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11790b57cec5SDimitry Andricvoid __cxx_atomic_store(__cxx_atomic_lock_impl<_Tp>* __a,  _Tp __val, memory_order) {
11800b57cec5SDimitry Andric  __a->__lock();
11810b57cec5SDimitry Andric  __a->__a_value = __val;
11820b57cec5SDimitry Andric  __a->__unlock();
11830b57cec5SDimitry Andric}
11840b57cec5SDimitry Andric
11850b57cec5SDimitry Andrictemplate <typename _Tp>
11860b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11870b57cec5SDimitry Andric_Tp __cxx_atomic_load(const volatile __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
11880b57cec5SDimitry Andric  return __a->__read();
11890b57cec5SDimitry Andric}
11900b57cec5SDimitry Andrictemplate <typename _Tp>
11910b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11920b57cec5SDimitry Andric_Tp __cxx_atomic_load(const __cxx_atomic_lock_impl<_Tp>* __a, memory_order) {
11930b57cec5SDimitry Andric  return __a->__read();
11940b57cec5SDimitry Andric}
11950b57cec5SDimitry Andric
11960b57cec5SDimitry Andrictemplate <typename _Tp>
11970b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
11980b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(volatile __cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
11990b57cec5SDimitry Andric  __a->__lock();
12000b57cec5SDimitry Andric  _Tp __old;
12010b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
12020b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __value);
12030b57cec5SDimitry Andric  __a->__unlock();
12040b57cec5SDimitry Andric  return __old;
12050b57cec5SDimitry Andric}
12060b57cec5SDimitry Andrictemplate <typename _Tp>
12070b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12080b57cec5SDimitry Andric_Tp __cxx_atomic_exchange(__cxx_atomic_lock_impl<_Tp>* __a, _Tp __value, memory_order) {
12090b57cec5SDimitry Andric  __a->__lock();
12100b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
12110b57cec5SDimitry Andric  __a->__a_value = __value;
12120b57cec5SDimitry Andric  __a->__unlock();
12130b57cec5SDimitry Andric  return __old;
12140b57cec5SDimitry Andric}
12150b57cec5SDimitry Andric
12160b57cec5SDimitry Andrictemplate <typename _Tp>
12170b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12180b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12190b57cec5SDimitry Andric                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
12200b57cec5SDimitry Andric  __a->__lock();
12210b57cec5SDimitry Andric  _Tp temp;
12220b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(temp, __a->__a_value);
12230b57cec5SDimitry Andric  bool __ret = temp == *__expected;
12240b57cec5SDimitry Andric  if(__ret)
12250b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(__a->__a_value, __value);
12260b57cec5SDimitry Andric  else
12270b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
12280b57cec5SDimitry Andric  __a->__unlock();
12290b57cec5SDimitry Andric  return __ret;
12300b57cec5SDimitry Andric}
12310b57cec5SDimitry Andrictemplate <typename _Tp>
12320b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12330b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
12340b57cec5SDimitry Andric                                          _Tp* __expected, _Tp __value, memory_order, memory_order) {
12350b57cec5SDimitry Andric  __a->__lock();
12360b57cec5SDimitry Andric  bool __ret = __a->__a_value == *__expected;
12370b57cec5SDimitry Andric  if(__ret)
12380b57cec5SDimitry Andric    __a->__a_value = __value;
12390b57cec5SDimitry Andric  else
12400b57cec5SDimitry Andric    *__expected = __a->__a_value;
12410b57cec5SDimitry Andric  __a->__unlock();
12420b57cec5SDimitry Andric  return __ret;
12430b57cec5SDimitry Andric}
12440b57cec5SDimitry Andric
12450b57cec5SDimitry Andrictemplate <typename _Tp>
12460b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12470b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12480b57cec5SDimitry Andric                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
12490b57cec5SDimitry Andric  __a->__lock();
12500b57cec5SDimitry Andric  _Tp temp;
12510b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(temp, __a->__a_value);
12520b57cec5SDimitry Andric  bool __ret = temp == *__expected;
12530b57cec5SDimitry Andric  if(__ret)
12540b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(__a->__a_value, __value);
12550b57cec5SDimitry Andric  else
12560b57cec5SDimitry Andric    __cxx_atomic_assign_volatile(*__expected, __a->__a_value);
12570b57cec5SDimitry Andric  __a->__unlock();
12580b57cec5SDimitry Andric  return __ret;
12590b57cec5SDimitry Andric}
12600b57cec5SDimitry Andrictemplate <typename _Tp>
12610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12620b57cec5SDimitry Andricbool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
12630b57cec5SDimitry Andric                                        _Tp* __expected, _Tp __value, memory_order, memory_order) {
12640b57cec5SDimitry Andric  __a->__lock();
12650b57cec5SDimitry Andric  bool __ret = __a->__a_value == *__expected;
12660b57cec5SDimitry Andric  if(__ret)
12670b57cec5SDimitry Andric    __a->__a_value = __value;
12680b57cec5SDimitry Andric  else
12690b57cec5SDimitry Andric    *__expected = __a->__a_value;
12700b57cec5SDimitry Andric  __a->__unlock();
12710b57cec5SDimitry Andric  return __ret;
12720b57cec5SDimitry Andric}
12730b57cec5SDimitry Andric
12740b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
12750b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12760b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp>* __a,
12770b57cec5SDimitry Andric                           _Td __delta, memory_order) {
12780b57cec5SDimitry Andric  __a->__lock();
12790b57cec5SDimitry Andric  _Tp __old;
12800b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
12810b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old + __delta));
12820b57cec5SDimitry Andric  __a->__unlock();
12830b57cec5SDimitry Andric  return __old;
12840b57cec5SDimitry Andric}
12850b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
12860b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12870b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp>* __a,
12880b57cec5SDimitry Andric                           _Td __delta, memory_order) {
12890b57cec5SDimitry Andric  __a->__lock();
12900b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
12910b57cec5SDimitry Andric  __a->__a_value += __delta;
12920b57cec5SDimitry Andric  __a->__unlock();
12930b57cec5SDimitry Andric  return __old;
12940b57cec5SDimitry Andric}
12950b57cec5SDimitry Andric
12960b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
12970b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
12980b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(volatile __cxx_atomic_lock_impl<_Tp*>* __a,
12990b57cec5SDimitry Andric                           ptrdiff_t __delta, memory_order) {
13000b57cec5SDimitry Andric  __a->__lock();
13010b57cec5SDimitry Andric  _Tp* __old;
13020b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13030b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, __old + __delta);
13040b57cec5SDimitry Andric  __a->__unlock();
13050b57cec5SDimitry Andric  return __old;
13060b57cec5SDimitry Andric}
13070b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
13080b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13090b57cec5SDimitry Andric_Tp* __cxx_atomic_fetch_add(__cxx_atomic_lock_impl<_Tp*>* __a,
13100b57cec5SDimitry Andric                           ptrdiff_t __delta, memory_order) {
13110b57cec5SDimitry Andric  __a->__lock();
13120b57cec5SDimitry Andric  _Tp* __old = __a->__a_value;
13130b57cec5SDimitry Andric  __a->__a_value += __delta;
13140b57cec5SDimitry Andric  __a->__unlock();
13150b57cec5SDimitry Andric  return __old;
13160b57cec5SDimitry Andric}
13170b57cec5SDimitry Andric
13180b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
13190b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13200b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13210b57cec5SDimitry Andric                           _Td __delta, memory_order) {
13220b57cec5SDimitry Andric  __a->__lock();
13230b57cec5SDimitry Andric  _Tp __old;
13240b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13250b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old - __delta));
13260b57cec5SDimitry Andric  __a->__unlock();
13270b57cec5SDimitry Andric  return __old;
13280b57cec5SDimitry Andric}
13290b57cec5SDimitry Andrictemplate <typename _Tp, typename _Td>
13300b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13310b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_sub(__cxx_atomic_lock_impl<_Tp>* __a,
13320b57cec5SDimitry Andric                           _Td __delta, memory_order) {
13330b57cec5SDimitry Andric  __a->__lock();
13340b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
13350b57cec5SDimitry Andric  __a->__a_value -= __delta;
13360b57cec5SDimitry Andric  __a->__unlock();
13370b57cec5SDimitry Andric  return __old;
13380b57cec5SDimitry Andric}
13390b57cec5SDimitry Andric
13400b57cec5SDimitry Andrictemplate <typename _Tp>
13410b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13420b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13430b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
13440b57cec5SDimitry Andric  __a->__lock();
13450b57cec5SDimitry Andric  _Tp __old;
13460b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13470b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old & __pattern));
13480b57cec5SDimitry Andric  __a->__unlock();
13490b57cec5SDimitry Andric  return __old;
13500b57cec5SDimitry Andric}
13510b57cec5SDimitry Andrictemplate <typename _Tp>
13520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13530b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_and(__cxx_atomic_lock_impl<_Tp>* __a,
13540b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
13550b57cec5SDimitry Andric  __a->__lock();
13560b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
13570b57cec5SDimitry Andric  __a->__a_value &= __pattern;
13580b57cec5SDimitry Andric  __a->__unlock();
13590b57cec5SDimitry Andric  return __old;
13600b57cec5SDimitry Andric}
13610b57cec5SDimitry Andric
13620b57cec5SDimitry Andrictemplate <typename _Tp>
13630b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13640b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13650b57cec5SDimitry Andric                          _Tp __pattern, memory_order) {
13660b57cec5SDimitry Andric  __a->__lock();
13670b57cec5SDimitry Andric  _Tp __old;
13680b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13690b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old | __pattern));
13700b57cec5SDimitry Andric  __a->__unlock();
13710b57cec5SDimitry Andric  return __old;
13720b57cec5SDimitry Andric}
13730b57cec5SDimitry Andrictemplate <typename _Tp>
13740b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13750b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_or(__cxx_atomic_lock_impl<_Tp>* __a,
13760b57cec5SDimitry Andric                          _Tp __pattern, memory_order) {
13770b57cec5SDimitry Andric  __a->__lock();
13780b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
13790b57cec5SDimitry Andric  __a->__a_value |= __pattern;
13800b57cec5SDimitry Andric  __a->__unlock();
13810b57cec5SDimitry Andric  return __old;
13820b57cec5SDimitry Andric}
13830b57cec5SDimitry Andric
13840b57cec5SDimitry Andrictemplate <typename _Tp>
13850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13860b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(volatile __cxx_atomic_lock_impl<_Tp>* __a,
13870b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
13880b57cec5SDimitry Andric  __a->__lock();
13890b57cec5SDimitry Andric  _Tp __old;
13900b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__old, __a->__a_value);
13910b57cec5SDimitry Andric  __cxx_atomic_assign_volatile(__a->__a_value, _Tp(__old ^ __pattern));
13920b57cec5SDimitry Andric  __a->__unlock();
13930b57cec5SDimitry Andric  return __old;
13940b57cec5SDimitry Andric}
13950b57cec5SDimitry Andrictemplate <typename _Tp>
13960b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
13970b57cec5SDimitry Andric_Tp __cxx_atomic_fetch_xor(__cxx_atomic_lock_impl<_Tp>* __a,
13980b57cec5SDimitry Andric                           _Tp __pattern, memory_order) {
13990b57cec5SDimitry Andric  __a->__lock();
14000b57cec5SDimitry Andric  _Tp __old = __a->__a_value;
14010b57cec5SDimitry Andric  __a->__a_value ^= __pattern;
14020b57cec5SDimitry Andric  __a->__unlock();
14030b57cec5SDimitry Andric  return __old;
14040b57cec5SDimitry Andric}
14050b57cec5SDimitry Andric
14060b57cec5SDimitry Andric#ifdef __cpp_lib_atomic_is_always_lock_free
14070b57cec5SDimitry Andric
14080b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free {
14090b57cec5SDimitry Andric    enum { __value = __atomic_always_lock_free(sizeof(_Tp), 0) }; };
14100b57cec5SDimitry Andric
14110b57cec5SDimitry Andric#else
14120b57cec5SDimitry Andric
14130b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free { enum { __value = false }; };
14140b57cec5SDimitry Andric// Implementations must match the C ATOMIC_*_LOCK_FREE macro values.
14150b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<bool> { enum { __value = 2 == ATOMIC_BOOL_LOCK_FREE }; };
14160b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14170b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<signed char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14180b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned char> { enum { __value = 2 == ATOMIC_CHAR_LOCK_FREE }; };
14190b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; };
14200b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; };
14210b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; };
14220b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
14230b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; };
14240b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
14250b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; };
14260b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
14270b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned long> { enum { __value = 2 == ATOMIC_LONG_LOCK_FREE }; };
14280b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
14290b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<unsigned long long> { enum { __value = 2 == ATOMIC_LLONG_LOCK_FREE }; };
14300b57cec5SDimitry Andrictemplate<typename _Tp> struct __cxx_is_always_lock_free<_Tp*> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
14310b57cec5SDimitry Andrictemplate<> struct __cxx_is_always_lock_free<std::nullptr_t> { enum { __value = 2 == ATOMIC_POINTER_LOCK_FREE }; };
14320b57cec5SDimitry Andric
14330b57cec5SDimitry Andric#endif //__cpp_lib_atomic_is_always_lock_free
14340b57cec5SDimitry Andric
14350b57cec5SDimitry Andrictemplate <typename _Tp,
14360b57cec5SDimitry Andric          typename _Base = typename conditional<__cxx_is_always_lock_free<_Tp>::__value,
14370b57cec5SDimitry Andric                                                __cxx_atomic_base_impl<_Tp>,
14380b57cec5SDimitry Andric                                                __cxx_atomic_lock_impl<_Tp> >::type>
14390b57cec5SDimitry Andric#else
14400b57cec5SDimitry Andrictemplate <typename _Tp,
14410b57cec5SDimitry Andric          typename _Base = __cxx_atomic_base_impl<_Tp> >
14420b57cec5SDimitry Andric#endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS
14430b57cec5SDimitry Andricstruct __cxx_atomic_impl : public _Base {
14440b57cec5SDimitry Andric
14450b57cec5SDimitry Andric#if _GNUC_VER >= 501
14460b57cec5SDimitry Andric    static_assert(is_trivially_copyable<_Tp>::value,
14470b57cec5SDimitry Andric      "std::atomic<Tp> requires that 'Tp' be a trivially copyable type");
14480b57cec5SDimitry Andric#endif
14490b57cec5SDimitry Andric
14500b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT
14510b57cec5SDimitry Andric  _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT
14520b57cec5SDimitry Andric    : _Base(value) {}
14530b57cec5SDimitry Andric};
14540b57cec5SDimitry Andric
14550b57cec5SDimitry Andric// general atomic<T>
14560b57cec5SDimitry Andric
14570b57cec5SDimitry Andrictemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
14580b57cec5SDimitry Andricstruct __atomic_base  // false
14590b57cec5SDimitry Andric{
14600b57cec5SDimitry Andric    mutable __cxx_atomic_impl<_Tp> __a_;
14610b57cec5SDimitry Andric
14620b57cec5SDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free)
14630b57cec5SDimitry Andric  static _LIBCPP_CONSTEXPR bool is_always_lock_free = __atomic_always_lock_free(sizeof(__a_), 0);
14640b57cec5SDimitry Andric#endif
14650b57cec5SDimitry Andric
14660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14670b57cec5SDimitry Andric    bool is_lock_free() const volatile _NOEXCEPT
14680b57cec5SDimitry Andric        {return __cxx_atomic_is_lock_free(sizeof(_Tp));}
14690b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14700b57cec5SDimitry Andric    bool is_lock_free() const _NOEXCEPT
14710b57cec5SDimitry Andric        {return static_cast<__atomic_base const volatile*>(this)->is_lock_free();}
14720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14730b57cec5SDimitry Andric    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
14740b57cec5SDimitry Andric      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
14750b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, __d, __m);}
14760b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14770b57cec5SDimitry Andric    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
14780b57cec5SDimitry Andric      _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
14790b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, __d, __m);}
14800b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14810b57cec5SDimitry Andric    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
14820b57cec5SDimitry Andric      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
14830b57cec5SDimitry Andric        {return __cxx_atomic_load(&__a_, __m);}
14840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14850b57cec5SDimitry Andric    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
14860b57cec5SDimitry Andric      _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
14870b57cec5SDimitry Andric        {return __cxx_atomic_load(&__a_, __m);}
14880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14890b57cec5SDimitry Andric    operator _Tp() const volatile _NOEXCEPT {return load();}
14900b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14910b57cec5SDimitry Andric    operator _Tp() const _NOEXCEPT          {return load();}
14920b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14930b57cec5SDimitry Andric    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
14940b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, __d, __m);}
14950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14960b57cec5SDimitry Andric    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
14970b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, __d, __m);}
14980b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
14990b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
15000b57cec5SDimitry Andric                               memory_order __s, memory_order __f) volatile _NOEXCEPT
15010b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
15020b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
15030b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15040b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
15050b57cec5SDimitry Andric                               memory_order __s, memory_order __f) _NOEXCEPT
15060b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
15070b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
15080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15090b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
15100b57cec5SDimitry Andric                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
15110b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
15120b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
15130b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15140b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
15150b57cec5SDimitry Andric                                 memory_order __s, memory_order __f) _NOEXCEPT
15160b57cec5SDimitry Andric      _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
15170b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
15180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15190b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
15200b57cec5SDimitry Andric                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15210b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
15220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15230b57cec5SDimitry Andric    bool compare_exchange_weak(_Tp& __e, _Tp __d,
15240b57cec5SDimitry Andric                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
15250b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
15260b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15270b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
15280b57cec5SDimitry Andric                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15290b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
15300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15310b57cec5SDimitry Andric    bool compare_exchange_strong(_Tp& __e, _Tp __d,
15320b57cec5SDimitry Andric                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
15330b57cec5SDimitry Andric        {return __cxx_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
15340b57cec5SDimitry Andric
15350b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15360b57cec5SDimitry Andric    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
15370b57cec5SDimitry Andric
15380b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
15390b57cec5SDimitry Andric    __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
15400b57cec5SDimitry Andric
15410b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
15420b57cec5SDimitry Andric    __atomic_base(const __atomic_base&) = delete;
15430b57cec5SDimitry Andric    __atomic_base& operator=(const __atomic_base&) = delete;
15440b57cec5SDimitry Andric    __atomic_base& operator=(const __atomic_base&) volatile = delete;
15450b57cec5SDimitry Andric#else
15460b57cec5SDimitry Andricprivate:
15470b57cec5SDimitry Andric    __atomic_base(const __atomic_base&);
15480b57cec5SDimitry Andric    __atomic_base& operator=(const __atomic_base&);
15490b57cec5SDimitry Andric    __atomic_base& operator=(const __atomic_base&) volatile;
15500b57cec5SDimitry Andric#endif
15510b57cec5SDimitry Andric};
15520b57cec5SDimitry Andric
15530b57cec5SDimitry Andric#if defined(__cpp_lib_atomic_is_always_lock_free)
15540b57cec5SDimitry Andrictemplate <class _Tp, bool __b>
15550b57cec5SDimitry Andric_LIBCPP_CONSTEXPR bool __atomic_base<_Tp, __b>::is_always_lock_free;
15560b57cec5SDimitry Andric#endif
15570b57cec5SDimitry Andric
15580b57cec5SDimitry Andric// atomic<Integral>
15590b57cec5SDimitry Andric
15600b57cec5SDimitry Andrictemplate <class _Tp>
15610b57cec5SDimitry Andricstruct __atomic_base<_Tp, true>
15620b57cec5SDimitry Andric    : public __atomic_base<_Tp, false>
15630b57cec5SDimitry Andric{
15640b57cec5SDimitry Andric    typedef __atomic_base<_Tp, false> __base;
15650b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15660b57cec5SDimitry Andric    __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
15670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15680b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
15690b57cec5SDimitry Andric
15700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15710b57cec5SDimitry Andric    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15720b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
15730b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15740b57cec5SDimitry Andric    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
15750b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
15760b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15770b57cec5SDimitry Andric    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15780b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
15790b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15800b57cec5SDimitry Andric    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
15810b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
15820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15830b57cec5SDimitry Andric    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15840b57cec5SDimitry Andric        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
15850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15860b57cec5SDimitry Andric    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
15870b57cec5SDimitry Andric        {return __cxx_atomic_fetch_and(&this->__a_, __op, __m);}
15880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15890b57cec5SDimitry Andric    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15900b57cec5SDimitry Andric        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
15910b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15920b57cec5SDimitry Andric    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
15930b57cec5SDimitry Andric        {return __cxx_atomic_fetch_or(&this->__a_, __op, __m);}
15940b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15950b57cec5SDimitry Andric    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
15960b57cec5SDimitry Andric        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
15970b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
15980b57cec5SDimitry Andric    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
15990b57cec5SDimitry Andric        {return __cxx_atomic_fetch_xor(&this->__a_, __op, __m);}
16000b57cec5SDimitry Andric
16010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16020b57cec5SDimitry Andric    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
16030b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16040b57cec5SDimitry Andric    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
16050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16060b57cec5SDimitry Andric    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
16070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16080b57cec5SDimitry Andric    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
16090b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16100b57cec5SDimitry Andric    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
16110b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16120b57cec5SDimitry Andric    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
16130b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16140b57cec5SDimitry Andric    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
16150b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16160b57cec5SDimitry Andric    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
16170b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16180b57cec5SDimitry Andric    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
16190b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16200b57cec5SDimitry Andric    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
16210b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16220b57cec5SDimitry Andric    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
16230b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16240b57cec5SDimitry Andric    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
16250b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16260b57cec5SDimitry Andric    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
16270b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16280b57cec5SDimitry Andric    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
16290b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16300b57cec5SDimitry Andric    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
16310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16320b57cec5SDimitry Andric    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
16330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16340b57cec5SDimitry Andric    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
16350b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16360b57cec5SDimitry Andric    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
16370b57cec5SDimitry Andric};
16380b57cec5SDimitry Andric
16390b57cec5SDimitry Andric// atomic<T>
16400b57cec5SDimitry Andric
16410b57cec5SDimitry Andrictemplate <class _Tp>
16420b57cec5SDimitry Andricstruct atomic
16430b57cec5SDimitry Andric    : public __atomic_base<_Tp>
16440b57cec5SDimitry Andric{
16450b57cec5SDimitry Andric    typedef __atomic_base<_Tp> __base;
16460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16470b57cec5SDimitry Andric    atomic() _NOEXCEPT _LIBCPP_DEFAULT
16480b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16490b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
16500b57cec5SDimitry Andric
16510b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16520b57cec5SDimitry Andric    _Tp operator=(_Tp __d) volatile _NOEXCEPT
16530b57cec5SDimitry Andric        {__base::store(__d); return __d;}
16540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16550b57cec5SDimitry Andric    _Tp operator=(_Tp __d) _NOEXCEPT
16560b57cec5SDimitry Andric        {__base::store(__d); return __d;}
16570b57cec5SDimitry Andric};
16580b57cec5SDimitry Andric
16590b57cec5SDimitry Andric// atomic<T*>
16600b57cec5SDimitry Andric
16610b57cec5SDimitry Andrictemplate <class _Tp>
16620b57cec5SDimitry Andricstruct atomic<_Tp*>
16630b57cec5SDimitry Andric    : public __atomic_base<_Tp*>
16640b57cec5SDimitry Andric{
16650b57cec5SDimitry Andric    typedef __atomic_base<_Tp*> __base;
16660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16670b57cec5SDimitry Andric    atomic() _NOEXCEPT _LIBCPP_DEFAULT
16680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16690b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
16700b57cec5SDimitry Andric
16710b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16720b57cec5SDimitry Andric    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
16730b57cec5SDimitry Andric        {__base::store(__d); return __d;}
16740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16750b57cec5SDimitry Andric    _Tp* operator=(_Tp* __d) _NOEXCEPT
16760b57cec5SDimitry Andric        {__base::store(__d); return __d;}
16770b57cec5SDimitry Andric
16780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16790b57cec5SDimitry Andric    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
16800b57cec5SDimitry Andric                                                                        volatile _NOEXCEPT
16810b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
16820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16830b57cec5SDimitry Andric    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16840b57cec5SDimitry Andric        {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);}
16850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16860b57cec5SDimitry Andric    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
16870b57cec5SDimitry Andric                                                                        volatile _NOEXCEPT
16880b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
16890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16900b57cec5SDimitry Andric    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
16910b57cec5SDimitry Andric        {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);}
16920b57cec5SDimitry Andric
16930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16940b57cec5SDimitry Andric    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
16950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16960b57cec5SDimitry Andric    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
16970b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
16980b57cec5SDimitry Andric    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
16990b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17000b57cec5SDimitry Andric    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
17010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17020b57cec5SDimitry Andric    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
17030b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17040b57cec5SDimitry Andric    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
17050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17060b57cec5SDimitry Andric    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
17070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17080b57cec5SDimitry Andric    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
17090b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17100b57cec5SDimitry Andric    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
17110b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17120b57cec5SDimitry Andric    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
17130b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17140b57cec5SDimitry Andric    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
17150b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17160b57cec5SDimitry Andric    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
17170b57cec5SDimitry Andric};
17180b57cec5SDimitry Andric
17190b57cec5SDimitry Andric// atomic_is_lock_free
17200b57cec5SDimitry Andric
17210b57cec5SDimitry Andrictemplate <class _Tp>
17220b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
17230b57cec5SDimitry Andricbool
17240b57cec5SDimitry Andricatomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
17250b57cec5SDimitry Andric{
17260b57cec5SDimitry Andric    return __o->is_lock_free();
17270b57cec5SDimitry Andric}
17280b57cec5SDimitry Andric
17290b57cec5SDimitry Andrictemplate <class _Tp>
17300b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
17310b57cec5SDimitry Andricbool
17320b57cec5SDimitry Andricatomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
17330b57cec5SDimitry Andric{
17340b57cec5SDimitry Andric    return __o->is_lock_free();
17350b57cec5SDimitry Andric}
17360b57cec5SDimitry Andric
17370b57cec5SDimitry Andric// atomic_init
17380b57cec5SDimitry Andric
17390b57cec5SDimitry Andrictemplate <class _Tp>
17400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
17410b57cec5SDimitry Andricvoid
17420b57cec5SDimitry Andricatomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
17430b57cec5SDimitry Andric{
17440b57cec5SDimitry Andric    __cxx_atomic_init(&__o->__a_, __d);
17450b57cec5SDimitry Andric}
17460b57cec5SDimitry Andric
17470b57cec5SDimitry Andrictemplate <class _Tp>
17480b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
17490b57cec5SDimitry Andricvoid
17500b57cec5SDimitry Andricatomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
17510b57cec5SDimitry Andric{
17520b57cec5SDimitry Andric    __cxx_atomic_init(&__o->__a_, __d);
17530b57cec5SDimitry Andric}
17540b57cec5SDimitry Andric
17550b57cec5SDimitry Andric// atomic_store
17560b57cec5SDimitry Andric
17570b57cec5SDimitry Andrictemplate <class _Tp>
17580b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
17590b57cec5SDimitry Andricvoid
17600b57cec5SDimitry Andricatomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
17610b57cec5SDimitry Andric{
17620b57cec5SDimitry Andric    __o->store(__d);
17630b57cec5SDimitry Andric}
17640b57cec5SDimitry Andric
17650b57cec5SDimitry Andrictemplate <class _Tp>
17660b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
17670b57cec5SDimitry Andricvoid
17680b57cec5SDimitry Andricatomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
17690b57cec5SDimitry Andric{
17700b57cec5SDimitry Andric    __o->store(__d);
17710b57cec5SDimitry Andric}
17720b57cec5SDimitry Andric
17730b57cec5SDimitry Andric// atomic_store_explicit
17740b57cec5SDimitry Andric
17750b57cec5SDimitry Andrictemplate <class _Tp>
17760b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
17770b57cec5SDimitry Andricvoid
17780b57cec5SDimitry Andricatomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
17790b57cec5SDimitry Andric  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
17800b57cec5SDimitry Andric{
17810b57cec5SDimitry Andric    __o->store(__d, __m);
17820b57cec5SDimitry Andric}
17830b57cec5SDimitry Andric
17840b57cec5SDimitry Andrictemplate <class _Tp>
17850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
17860b57cec5SDimitry Andricvoid
17870b57cec5SDimitry Andricatomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
17880b57cec5SDimitry Andric  _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
17890b57cec5SDimitry Andric{
17900b57cec5SDimitry Andric    __o->store(__d, __m);
17910b57cec5SDimitry Andric}
17920b57cec5SDimitry Andric
17930b57cec5SDimitry Andric// atomic_load
17940b57cec5SDimitry Andric
17950b57cec5SDimitry Andrictemplate <class _Tp>
17960b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
17970b57cec5SDimitry Andric_Tp
17980b57cec5SDimitry Andricatomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
17990b57cec5SDimitry Andric{
18000b57cec5SDimitry Andric    return __o->load();
18010b57cec5SDimitry Andric}
18020b57cec5SDimitry Andric
18030b57cec5SDimitry Andrictemplate <class _Tp>
18040b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18050b57cec5SDimitry Andric_Tp
18060b57cec5SDimitry Andricatomic_load(const atomic<_Tp>* __o) _NOEXCEPT
18070b57cec5SDimitry Andric{
18080b57cec5SDimitry Andric    return __o->load();
18090b57cec5SDimitry Andric}
18100b57cec5SDimitry Andric
18110b57cec5SDimitry Andric// atomic_load_explicit
18120b57cec5SDimitry Andric
18130b57cec5SDimitry Andrictemplate <class _Tp>
18140b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18150b57cec5SDimitry Andric_Tp
18160b57cec5SDimitry Andricatomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
18170b57cec5SDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
18180b57cec5SDimitry Andric{
18190b57cec5SDimitry Andric    return __o->load(__m);
18200b57cec5SDimitry Andric}
18210b57cec5SDimitry Andric
18220b57cec5SDimitry Andrictemplate <class _Tp>
18230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18240b57cec5SDimitry Andric_Tp
18250b57cec5SDimitry Andricatomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
18260b57cec5SDimitry Andric  _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m)
18270b57cec5SDimitry Andric{
18280b57cec5SDimitry Andric    return __o->load(__m);
18290b57cec5SDimitry Andric}
18300b57cec5SDimitry Andric
18310b57cec5SDimitry Andric// atomic_exchange
18320b57cec5SDimitry Andric
18330b57cec5SDimitry Andrictemplate <class _Tp>
18340b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18350b57cec5SDimitry Andric_Tp
18360b57cec5SDimitry Andricatomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
18370b57cec5SDimitry Andric{
18380b57cec5SDimitry Andric    return __o->exchange(__d);
18390b57cec5SDimitry Andric}
18400b57cec5SDimitry Andric
18410b57cec5SDimitry Andrictemplate <class _Tp>
18420b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18430b57cec5SDimitry Andric_Tp
18440b57cec5SDimitry Andricatomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
18450b57cec5SDimitry Andric{
18460b57cec5SDimitry Andric    return __o->exchange(__d);
18470b57cec5SDimitry Andric}
18480b57cec5SDimitry Andric
18490b57cec5SDimitry Andric// atomic_exchange_explicit
18500b57cec5SDimitry Andric
18510b57cec5SDimitry Andrictemplate <class _Tp>
18520b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18530b57cec5SDimitry Andric_Tp
18540b57cec5SDimitry Andricatomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
18550b57cec5SDimitry Andric{
18560b57cec5SDimitry Andric    return __o->exchange(__d, __m);
18570b57cec5SDimitry Andric}
18580b57cec5SDimitry Andric
18590b57cec5SDimitry Andrictemplate <class _Tp>
18600b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18610b57cec5SDimitry Andric_Tp
18620b57cec5SDimitry Andricatomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
18630b57cec5SDimitry Andric{
18640b57cec5SDimitry Andric    return __o->exchange(__d, __m);
18650b57cec5SDimitry Andric}
18660b57cec5SDimitry Andric
18670b57cec5SDimitry Andric// atomic_compare_exchange_weak
18680b57cec5SDimitry Andric
18690b57cec5SDimitry Andrictemplate <class _Tp>
18700b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18710b57cec5SDimitry Andricbool
18720b57cec5SDimitry Andricatomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
18730b57cec5SDimitry Andric{
18740b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d);
18750b57cec5SDimitry Andric}
18760b57cec5SDimitry Andric
18770b57cec5SDimitry Andrictemplate <class _Tp>
18780b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18790b57cec5SDimitry Andricbool
18800b57cec5SDimitry Andricatomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
18810b57cec5SDimitry Andric{
18820b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d);
18830b57cec5SDimitry Andric}
18840b57cec5SDimitry Andric
18850b57cec5SDimitry Andric// atomic_compare_exchange_strong
18860b57cec5SDimitry Andric
18870b57cec5SDimitry Andrictemplate <class _Tp>
18880b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18890b57cec5SDimitry Andricbool
18900b57cec5SDimitry Andricatomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
18910b57cec5SDimitry Andric{
18920b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d);
18930b57cec5SDimitry Andric}
18940b57cec5SDimitry Andric
18950b57cec5SDimitry Andrictemplate <class _Tp>
18960b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18970b57cec5SDimitry Andricbool
18980b57cec5SDimitry Andricatomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
18990b57cec5SDimitry Andric{
19000b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d);
19010b57cec5SDimitry Andric}
19020b57cec5SDimitry Andric
19030b57cec5SDimitry Andric// atomic_compare_exchange_weak_explicit
19040b57cec5SDimitry Andric
19050b57cec5SDimitry Andrictemplate <class _Tp>
19060b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19070b57cec5SDimitry Andricbool
19080b57cec5SDimitry Andricatomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
19090b57cec5SDimitry Andric                                      _Tp __d,
19100b57cec5SDimitry Andric                                      memory_order __s, memory_order __f) _NOEXCEPT
19110b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
19120b57cec5SDimitry Andric{
19130b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d, __s, __f);
19140b57cec5SDimitry Andric}
19150b57cec5SDimitry Andric
19160b57cec5SDimitry Andrictemplate <class _Tp>
19170b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19180b57cec5SDimitry Andricbool
19190b57cec5SDimitry Andricatomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
19200b57cec5SDimitry Andric                                      memory_order __s, memory_order __f) _NOEXCEPT
19210b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
19220b57cec5SDimitry Andric{
19230b57cec5SDimitry Andric    return __o->compare_exchange_weak(*__e, __d, __s, __f);
19240b57cec5SDimitry Andric}
19250b57cec5SDimitry Andric
19260b57cec5SDimitry Andric// atomic_compare_exchange_strong_explicit
19270b57cec5SDimitry Andric
19280b57cec5SDimitry Andrictemplate <class _Tp>
19290b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19300b57cec5SDimitry Andricbool
19310b57cec5SDimitry Andricatomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
19320b57cec5SDimitry Andric                                        _Tp* __e, _Tp __d,
19330b57cec5SDimitry Andric                                        memory_order __s, memory_order __f) _NOEXCEPT
19340b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
19350b57cec5SDimitry Andric{
19360b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d, __s, __f);
19370b57cec5SDimitry Andric}
19380b57cec5SDimitry Andric
19390b57cec5SDimitry Andrictemplate <class _Tp>
19400b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19410b57cec5SDimitry Andricbool
19420b57cec5SDimitry Andricatomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
19430b57cec5SDimitry Andric                                        _Tp __d,
19440b57cec5SDimitry Andric                                        memory_order __s, memory_order __f) _NOEXCEPT
19450b57cec5SDimitry Andric  _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
19460b57cec5SDimitry Andric{
19470b57cec5SDimitry Andric    return __o->compare_exchange_strong(*__e, __d, __s, __f);
19480b57cec5SDimitry Andric}
19490b57cec5SDimitry Andric
19500b57cec5SDimitry Andric// atomic_fetch_add
19510b57cec5SDimitry Andric
19520b57cec5SDimitry Andrictemplate <class _Tp>
19530b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19540b57cec5SDimitry Andrictypename enable_if
19550b57cec5SDimitry Andric<
19560b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
19570b57cec5SDimitry Andric    _Tp
19580b57cec5SDimitry Andric>::type
19590b57cec5SDimitry Andricatomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
19600b57cec5SDimitry Andric{
19610b57cec5SDimitry Andric    return __o->fetch_add(__op);
19620b57cec5SDimitry Andric}
19630b57cec5SDimitry Andric
19640b57cec5SDimitry Andrictemplate <class _Tp>
19650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19660b57cec5SDimitry Andrictypename enable_if
19670b57cec5SDimitry Andric<
19680b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
19690b57cec5SDimitry Andric    _Tp
19700b57cec5SDimitry Andric>::type
19710b57cec5SDimitry Andricatomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
19720b57cec5SDimitry Andric{
19730b57cec5SDimitry Andric    return __o->fetch_add(__op);
19740b57cec5SDimitry Andric}
19750b57cec5SDimitry Andric
19760b57cec5SDimitry Andrictemplate <class _Tp>
19770b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19780b57cec5SDimitry Andric_Tp*
19790b57cec5SDimitry Andricatomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
19800b57cec5SDimitry Andric{
19810b57cec5SDimitry Andric    return __o->fetch_add(__op);
19820b57cec5SDimitry Andric}
19830b57cec5SDimitry Andric
19840b57cec5SDimitry Andrictemplate <class _Tp>
19850b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19860b57cec5SDimitry Andric_Tp*
19870b57cec5SDimitry Andricatomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
19880b57cec5SDimitry Andric{
19890b57cec5SDimitry Andric    return __o->fetch_add(__op);
19900b57cec5SDimitry Andric}
19910b57cec5SDimitry Andric
19920b57cec5SDimitry Andric// atomic_fetch_add_explicit
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andrictemplate <class _Tp>
19950b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
19960b57cec5SDimitry Andrictypename enable_if
19970b57cec5SDimitry Andric<
19980b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
19990b57cec5SDimitry Andric    _Tp
20000b57cec5SDimitry Andric>::type
20010b57cec5SDimitry Andricatomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
20020b57cec5SDimitry Andric{
20030b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
20040b57cec5SDimitry Andric}
20050b57cec5SDimitry Andric
20060b57cec5SDimitry Andrictemplate <class _Tp>
20070b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20080b57cec5SDimitry Andrictypename enable_if
20090b57cec5SDimitry Andric<
20100b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
20110b57cec5SDimitry Andric    _Tp
20120b57cec5SDimitry Andric>::type
20130b57cec5SDimitry Andricatomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
20140b57cec5SDimitry Andric{
20150b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
20160b57cec5SDimitry Andric}
20170b57cec5SDimitry Andric
20180b57cec5SDimitry Andrictemplate <class _Tp>
20190b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20200b57cec5SDimitry Andric_Tp*
20210b57cec5SDimitry Andricatomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
20220b57cec5SDimitry Andric                          memory_order __m) _NOEXCEPT
20230b57cec5SDimitry Andric{
20240b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
20250b57cec5SDimitry Andric}
20260b57cec5SDimitry Andric
20270b57cec5SDimitry Andrictemplate <class _Tp>
20280b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20290b57cec5SDimitry Andric_Tp*
20300b57cec5SDimitry Andricatomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
20310b57cec5SDimitry Andric{
20320b57cec5SDimitry Andric    return __o->fetch_add(__op, __m);
20330b57cec5SDimitry Andric}
20340b57cec5SDimitry Andric
20350b57cec5SDimitry Andric// atomic_fetch_sub
20360b57cec5SDimitry Andric
20370b57cec5SDimitry Andrictemplate <class _Tp>
20380b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20390b57cec5SDimitry Andrictypename enable_if
20400b57cec5SDimitry Andric<
20410b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
20420b57cec5SDimitry Andric    _Tp
20430b57cec5SDimitry Andric>::type
20440b57cec5SDimitry Andricatomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
20450b57cec5SDimitry Andric{
20460b57cec5SDimitry Andric    return __o->fetch_sub(__op);
20470b57cec5SDimitry Andric}
20480b57cec5SDimitry Andric
20490b57cec5SDimitry Andrictemplate <class _Tp>
20500b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20510b57cec5SDimitry Andrictypename enable_if
20520b57cec5SDimitry Andric<
20530b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
20540b57cec5SDimitry Andric    _Tp
20550b57cec5SDimitry Andric>::type
20560b57cec5SDimitry Andricatomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
20570b57cec5SDimitry Andric{
20580b57cec5SDimitry Andric    return __o->fetch_sub(__op);
20590b57cec5SDimitry Andric}
20600b57cec5SDimitry Andric
20610b57cec5SDimitry Andrictemplate <class _Tp>
20620b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20630b57cec5SDimitry Andric_Tp*
20640b57cec5SDimitry Andricatomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
20650b57cec5SDimitry Andric{
20660b57cec5SDimitry Andric    return __o->fetch_sub(__op);
20670b57cec5SDimitry Andric}
20680b57cec5SDimitry Andric
20690b57cec5SDimitry Andrictemplate <class _Tp>
20700b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20710b57cec5SDimitry Andric_Tp*
20720b57cec5SDimitry Andricatomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
20730b57cec5SDimitry Andric{
20740b57cec5SDimitry Andric    return __o->fetch_sub(__op);
20750b57cec5SDimitry Andric}
20760b57cec5SDimitry Andric
20770b57cec5SDimitry Andric// atomic_fetch_sub_explicit
20780b57cec5SDimitry Andric
20790b57cec5SDimitry Andrictemplate <class _Tp>
20800b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20810b57cec5SDimitry Andrictypename enable_if
20820b57cec5SDimitry Andric<
20830b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
20840b57cec5SDimitry Andric    _Tp
20850b57cec5SDimitry Andric>::type
20860b57cec5SDimitry Andricatomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
20870b57cec5SDimitry Andric{
20880b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
20890b57cec5SDimitry Andric}
20900b57cec5SDimitry Andric
20910b57cec5SDimitry Andrictemplate <class _Tp>
20920b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20930b57cec5SDimitry Andrictypename enable_if
20940b57cec5SDimitry Andric<
20950b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
20960b57cec5SDimitry Andric    _Tp
20970b57cec5SDimitry Andric>::type
20980b57cec5SDimitry Andricatomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
20990b57cec5SDimitry Andric{
21000b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
21010b57cec5SDimitry Andric}
21020b57cec5SDimitry Andric
21030b57cec5SDimitry Andrictemplate <class _Tp>
21040b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21050b57cec5SDimitry Andric_Tp*
21060b57cec5SDimitry Andricatomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
21070b57cec5SDimitry Andric                          memory_order __m) _NOEXCEPT
21080b57cec5SDimitry Andric{
21090b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
21100b57cec5SDimitry Andric}
21110b57cec5SDimitry Andric
21120b57cec5SDimitry Andrictemplate <class _Tp>
21130b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21140b57cec5SDimitry Andric_Tp*
21150b57cec5SDimitry Andricatomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
21160b57cec5SDimitry Andric{
21170b57cec5SDimitry Andric    return __o->fetch_sub(__op, __m);
21180b57cec5SDimitry Andric}
21190b57cec5SDimitry Andric
21200b57cec5SDimitry Andric// atomic_fetch_and
21210b57cec5SDimitry Andric
21220b57cec5SDimitry Andrictemplate <class _Tp>
21230b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21240b57cec5SDimitry Andrictypename enable_if
21250b57cec5SDimitry Andric<
21260b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
21270b57cec5SDimitry Andric    _Tp
21280b57cec5SDimitry Andric>::type
21290b57cec5SDimitry Andricatomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
21300b57cec5SDimitry Andric{
21310b57cec5SDimitry Andric    return __o->fetch_and(__op);
21320b57cec5SDimitry Andric}
21330b57cec5SDimitry Andric
21340b57cec5SDimitry Andrictemplate <class _Tp>
21350b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21360b57cec5SDimitry Andrictypename enable_if
21370b57cec5SDimitry Andric<
21380b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
21390b57cec5SDimitry Andric    _Tp
21400b57cec5SDimitry Andric>::type
21410b57cec5SDimitry Andricatomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
21420b57cec5SDimitry Andric{
21430b57cec5SDimitry Andric    return __o->fetch_and(__op);
21440b57cec5SDimitry Andric}
21450b57cec5SDimitry Andric
21460b57cec5SDimitry Andric// atomic_fetch_and_explicit
21470b57cec5SDimitry Andric
21480b57cec5SDimitry Andrictemplate <class _Tp>
21490b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21500b57cec5SDimitry Andrictypename enable_if
21510b57cec5SDimitry Andric<
21520b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
21530b57cec5SDimitry Andric    _Tp
21540b57cec5SDimitry Andric>::type
21550b57cec5SDimitry Andricatomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
21560b57cec5SDimitry Andric{
21570b57cec5SDimitry Andric    return __o->fetch_and(__op, __m);
21580b57cec5SDimitry Andric}
21590b57cec5SDimitry Andric
21600b57cec5SDimitry Andrictemplate <class _Tp>
21610b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21620b57cec5SDimitry Andrictypename enable_if
21630b57cec5SDimitry Andric<
21640b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
21650b57cec5SDimitry Andric    _Tp
21660b57cec5SDimitry Andric>::type
21670b57cec5SDimitry Andricatomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
21680b57cec5SDimitry Andric{
21690b57cec5SDimitry Andric    return __o->fetch_and(__op, __m);
21700b57cec5SDimitry Andric}
21710b57cec5SDimitry Andric
21720b57cec5SDimitry Andric// atomic_fetch_or
21730b57cec5SDimitry Andric
21740b57cec5SDimitry Andrictemplate <class _Tp>
21750b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21760b57cec5SDimitry Andrictypename enable_if
21770b57cec5SDimitry Andric<
21780b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
21790b57cec5SDimitry Andric    _Tp
21800b57cec5SDimitry Andric>::type
21810b57cec5SDimitry Andricatomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
21820b57cec5SDimitry Andric{
21830b57cec5SDimitry Andric    return __o->fetch_or(__op);
21840b57cec5SDimitry Andric}
21850b57cec5SDimitry Andric
21860b57cec5SDimitry Andrictemplate <class _Tp>
21870b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
21880b57cec5SDimitry Andrictypename enable_if
21890b57cec5SDimitry Andric<
21900b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
21910b57cec5SDimitry Andric    _Tp
21920b57cec5SDimitry Andric>::type
21930b57cec5SDimitry Andricatomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
21940b57cec5SDimitry Andric{
21950b57cec5SDimitry Andric    return __o->fetch_or(__op);
21960b57cec5SDimitry Andric}
21970b57cec5SDimitry Andric
21980b57cec5SDimitry Andric// atomic_fetch_or_explicit
21990b57cec5SDimitry Andric
22000b57cec5SDimitry Andrictemplate <class _Tp>
22010b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22020b57cec5SDimitry Andrictypename enable_if
22030b57cec5SDimitry Andric<
22040b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
22050b57cec5SDimitry Andric    _Tp
22060b57cec5SDimitry Andric>::type
22070b57cec5SDimitry Andricatomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
22080b57cec5SDimitry Andric{
22090b57cec5SDimitry Andric    return __o->fetch_or(__op, __m);
22100b57cec5SDimitry Andric}
22110b57cec5SDimitry Andric
22120b57cec5SDimitry Andrictemplate <class _Tp>
22130b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22140b57cec5SDimitry Andrictypename enable_if
22150b57cec5SDimitry Andric<
22160b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
22170b57cec5SDimitry Andric    _Tp
22180b57cec5SDimitry Andric>::type
22190b57cec5SDimitry Andricatomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
22200b57cec5SDimitry Andric{
22210b57cec5SDimitry Andric    return __o->fetch_or(__op, __m);
22220b57cec5SDimitry Andric}
22230b57cec5SDimitry Andric
22240b57cec5SDimitry Andric// atomic_fetch_xor
22250b57cec5SDimitry Andric
22260b57cec5SDimitry Andrictemplate <class _Tp>
22270b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22280b57cec5SDimitry Andrictypename enable_if
22290b57cec5SDimitry Andric<
22300b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
22310b57cec5SDimitry Andric    _Tp
22320b57cec5SDimitry Andric>::type
22330b57cec5SDimitry Andricatomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
22340b57cec5SDimitry Andric{
22350b57cec5SDimitry Andric    return __o->fetch_xor(__op);
22360b57cec5SDimitry Andric}
22370b57cec5SDimitry Andric
22380b57cec5SDimitry Andrictemplate <class _Tp>
22390b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22400b57cec5SDimitry Andrictypename enable_if
22410b57cec5SDimitry Andric<
22420b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
22430b57cec5SDimitry Andric    _Tp
22440b57cec5SDimitry Andric>::type
22450b57cec5SDimitry Andricatomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
22460b57cec5SDimitry Andric{
22470b57cec5SDimitry Andric    return __o->fetch_xor(__op);
22480b57cec5SDimitry Andric}
22490b57cec5SDimitry Andric
22500b57cec5SDimitry Andric// atomic_fetch_xor_explicit
22510b57cec5SDimitry Andric
22520b57cec5SDimitry Andrictemplate <class _Tp>
22530b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22540b57cec5SDimitry Andrictypename enable_if
22550b57cec5SDimitry Andric<
22560b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
22570b57cec5SDimitry Andric    _Tp
22580b57cec5SDimitry Andric>::type
22590b57cec5SDimitry Andricatomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
22600b57cec5SDimitry Andric{
22610b57cec5SDimitry Andric    return __o->fetch_xor(__op, __m);
22620b57cec5SDimitry Andric}
22630b57cec5SDimitry Andric
22640b57cec5SDimitry Andrictemplate <class _Tp>
22650b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
22660b57cec5SDimitry Andrictypename enable_if
22670b57cec5SDimitry Andric<
22680b57cec5SDimitry Andric    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
22690b57cec5SDimitry Andric    _Tp
22700b57cec5SDimitry Andric>::type
22710b57cec5SDimitry Andricatomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
22720b57cec5SDimitry Andric{
22730b57cec5SDimitry Andric    return __o->fetch_xor(__op, __m);
22740b57cec5SDimitry Andric}
22750b57cec5SDimitry Andric
22760b57cec5SDimitry Andric// flag type and operations
22770b57cec5SDimitry Andric
22780b57cec5SDimitry Andrictypedef struct atomic_flag
22790b57cec5SDimitry Andric{
22800b57cec5SDimitry Andric    __cxx_atomic_impl<_LIBCPP_ATOMIC_FLAG_TYPE> __a_;
22810b57cec5SDimitry Andric
22820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
22830b57cec5SDimitry Andric    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
22840b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
22850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
22860b57cec5SDimitry Andric    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
22870b57cec5SDimitry Andric        {return __cxx_atomic_exchange(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(true), __m);}
22880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
22890b57cec5SDimitry Andric    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
22900b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
22910b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
22920b57cec5SDimitry Andric    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
22930b57cec5SDimitry Andric        {__cxx_atomic_store(&__a_, _LIBCPP_ATOMIC_FLAG_TYPE(false), __m);}
22940b57cec5SDimitry Andric
22950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
22960b57cec5SDimitry Andric    atomic_flag() _NOEXCEPT _LIBCPP_DEFAULT
22970b57cec5SDimitry Andric
22980b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
22990b57cec5SDimitry Andric    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {} // EXTENSION
23000b57cec5SDimitry Andric
23010b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
23020b57cec5SDimitry Andric    atomic_flag(const atomic_flag&) = delete;
23030b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) = delete;
23040b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile = delete;
23050b57cec5SDimitry Andric#else
23060b57cec5SDimitry Andricprivate:
23070b57cec5SDimitry Andric    atomic_flag(const atomic_flag&);
23080b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&);
23090b57cec5SDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile;
23100b57cec5SDimitry Andric#endif
23110b57cec5SDimitry Andric} atomic_flag;
23120b57cec5SDimitry Andric
23130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23140b57cec5SDimitry Andricbool
23150b57cec5SDimitry Andricatomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
23160b57cec5SDimitry Andric{
23170b57cec5SDimitry Andric    return __o->test_and_set();
23180b57cec5SDimitry Andric}
23190b57cec5SDimitry Andric
23200b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23210b57cec5SDimitry Andricbool
23220b57cec5SDimitry Andricatomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
23230b57cec5SDimitry Andric{
23240b57cec5SDimitry Andric    return __o->test_and_set();
23250b57cec5SDimitry Andric}
23260b57cec5SDimitry Andric
23270b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23280b57cec5SDimitry Andricbool
23290b57cec5SDimitry Andricatomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
23300b57cec5SDimitry Andric{
23310b57cec5SDimitry Andric    return __o->test_and_set(__m);
23320b57cec5SDimitry Andric}
23330b57cec5SDimitry Andric
23340b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23350b57cec5SDimitry Andricbool
23360b57cec5SDimitry Andricatomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
23370b57cec5SDimitry Andric{
23380b57cec5SDimitry Andric    return __o->test_and_set(__m);
23390b57cec5SDimitry Andric}
23400b57cec5SDimitry Andric
23410b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23420b57cec5SDimitry Andricvoid
23430b57cec5SDimitry Andricatomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
23440b57cec5SDimitry Andric{
23450b57cec5SDimitry Andric    __o->clear();
23460b57cec5SDimitry Andric}
23470b57cec5SDimitry Andric
23480b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23490b57cec5SDimitry Andricvoid
23500b57cec5SDimitry Andricatomic_flag_clear(atomic_flag* __o) _NOEXCEPT
23510b57cec5SDimitry Andric{
23520b57cec5SDimitry Andric    __o->clear();
23530b57cec5SDimitry Andric}
23540b57cec5SDimitry Andric
23550b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23560b57cec5SDimitry Andricvoid
23570b57cec5SDimitry Andricatomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
23580b57cec5SDimitry Andric{
23590b57cec5SDimitry Andric    __o->clear(__m);
23600b57cec5SDimitry Andric}
23610b57cec5SDimitry Andric
23620b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23630b57cec5SDimitry Andricvoid
23640b57cec5SDimitry Andricatomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
23650b57cec5SDimitry Andric{
23660b57cec5SDimitry Andric    __o->clear(__m);
23670b57cec5SDimitry Andric}
23680b57cec5SDimitry Andric
23690b57cec5SDimitry Andric// fences
23700b57cec5SDimitry Andric
23710b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23720b57cec5SDimitry Andricvoid
23730b57cec5SDimitry Andricatomic_thread_fence(memory_order __m) _NOEXCEPT
23740b57cec5SDimitry Andric{
23750b57cec5SDimitry Andric    __cxx_atomic_thread_fence(__m);
23760b57cec5SDimitry Andric}
23770b57cec5SDimitry Andric
23780b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
23790b57cec5SDimitry Andricvoid
23800b57cec5SDimitry Andricatomic_signal_fence(memory_order __m) _NOEXCEPT
23810b57cec5SDimitry Andric{
23820b57cec5SDimitry Andric    __cxx_atomic_signal_fence(__m);
23830b57cec5SDimitry Andric}
23840b57cec5SDimitry Andric
23850b57cec5SDimitry Andric// Atomics for standard typedef types
23860b57cec5SDimitry Andric
23870b57cec5SDimitry Andrictypedef atomic<bool>               atomic_bool;
23880b57cec5SDimitry Andrictypedef atomic<char>               atomic_char;
23890b57cec5SDimitry Andrictypedef atomic<signed char>        atomic_schar;
23900b57cec5SDimitry Andrictypedef atomic<unsigned char>      atomic_uchar;
23910b57cec5SDimitry Andrictypedef atomic<short>              atomic_short;
23920b57cec5SDimitry Andrictypedef atomic<unsigned short>     atomic_ushort;
23930b57cec5SDimitry Andrictypedef atomic<int>                atomic_int;
23940b57cec5SDimitry Andrictypedef atomic<unsigned int>       atomic_uint;
23950b57cec5SDimitry Andrictypedef atomic<long>               atomic_long;
23960b57cec5SDimitry Andrictypedef atomic<unsigned long>      atomic_ulong;
23970b57cec5SDimitry Andrictypedef atomic<long long>          atomic_llong;
23980b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong;
23990b57cec5SDimitry Andrictypedef atomic<char16_t>           atomic_char16_t;
24000b57cec5SDimitry Andrictypedef atomic<char32_t>           atomic_char32_t;
24010b57cec5SDimitry Andrictypedef atomic<wchar_t>            atomic_wchar_t;
24020b57cec5SDimitry Andric
24030b57cec5SDimitry Andrictypedef atomic<int_least8_t>   atomic_int_least8_t;
24040b57cec5SDimitry Andrictypedef atomic<uint_least8_t>  atomic_uint_least8_t;
24050b57cec5SDimitry Andrictypedef atomic<int_least16_t>  atomic_int_least16_t;
24060b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t;
24070b57cec5SDimitry Andrictypedef atomic<int_least32_t>  atomic_int_least32_t;
24080b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t;
24090b57cec5SDimitry Andrictypedef atomic<int_least64_t>  atomic_int_least64_t;
24100b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t;
24110b57cec5SDimitry Andric
24120b57cec5SDimitry Andrictypedef atomic<int_fast8_t>   atomic_int_fast8_t;
24130b57cec5SDimitry Andrictypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
24140b57cec5SDimitry Andrictypedef atomic<int_fast16_t>  atomic_int_fast16_t;
24150b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
24160b57cec5SDimitry Andrictypedef atomic<int_fast32_t>  atomic_int_fast32_t;
24170b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
24180b57cec5SDimitry Andrictypedef atomic<int_fast64_t>  atomic_int_fast64_t;
24190b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
24200b57cec5SDimitry Andric
24210b57cec5SDimitry Andrictypedef atomic< int8_t>  atomic_int8_t;
24220b57cec5SDimitry Andrictypedef atomic<uint8_t>  atomic_uint8_t;
24230b57cec5SDimitry Andrictypedef atomic< int16_t> atomic_int16_t;
24240b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t;
24250b57cec5SDimitry Andrictypedef atomic< int32_t> atomic_int32_t;
24260b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t;
24270b57cec5SDimitry Andrictypedef atomic< int64_t> atomic_int64_t;
24280b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t;
24290b57cec5SDimitry Andric
24300b57cec5SDimitry Andrictypedef atomic<intptr_t>  atomic_intptr_t;
24310b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t;
24320b57cec5SDimitry Andrictypedef atomic<size_t>    atomic_size_t;
24330b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
24340b57cec5SDimitry Andrictypedef atomic<intmax_t>  atomic_intmax_t;
24350b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t;
24360b57cec5SDimitry Andric
24370b57cec5SDimitry Andric#define ATOMIC_FLAG_INIT {false}
24380b57cec5SDimitry Andric#define ATOMIC_VAR_INIT(__v) {__v}
24390b57cec5SDimitry Andric
24400b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
24410b57cec5SDimitry Andric
24420b57cec5SDimitry Andric#endif  // _LIBCPP_ATOMIC
2443