xref: /freebsd/contrib/llvm-project/libcxx/include/atomic (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric// -*- C++ -*-
2349cc55cSDimitry Andric//===----------------------------------------------------------------------===//
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
19e8d8bef9SDimitry Andric// feature test macro [version.syn]
200b57cec5SDimitry Andric
21e8d8bef9SDimitry Andric#define __cpp_lib_atomic_is_always_lock_free
22e8d8bef9SDimitry Andric#define __cpp_lib_atomic_flag_test
23e8d8bef9SDimitry Andric#define __cpp_lib_atomic_lock_free_type_aliases
24e8d8bef9SDimitry Andric#define __cpp_lib_atomic_wait
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric // order and consistency
270b57cec5SDimitry Andric
280b57cec5SDimitry Andric enum memory_order: unspecified // enum class in C++20
290b57cec5SDimitry Andric {
300b57cec5SDimitry Andric    relaxed,
310b57cec5SDimitry Andric    consume, // load-consume
320b57cec5SDimitry Andric    acquire, // load-acquire
330b57cec5SDimitry Andric    release, // store-release
340b57cec5SDimitry Andric    acq_rel, // store-release load-acquire
350b57cec5SDimitry Andric    seq_cst // store-release load-acquire
360b57cec5SDimitry Andric };
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric inline constexpr auto memory_order_relaxed = memory_order::relaxed;
390b57cec5SDimitry Andric inline constexpr auto memory_order_consume = memory_order::consume;
400b57cec5SDimitry Andric inline constexpr auto memory_order_acquire = memory_order::acquire;
410b57cec5SDimitry Andric inline constexpr auto memory_order_release = memory_order::release;
420b57cec5SDimitry Andric inline constexpr auto memory_order_acq_rel = memory_order::acq_rel;
430b57cec5SDimitry Andric inline constexpr auto memory_order_seq_cst = memory_order::seq_cst;
440b57cec5SDimitry Andric
450b57cec5SDimitry Andrictemplate <class T> T kill_dependency(T y) noexcept;
460b57cec5SDimitry Andric
470b57cec5SDimitry Andric// lock-free property
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric#define ATOMIC_BOOL_LOCK_FREE unspecified
500b57cec5SDimitry Andric#define ATOMIC_CHAR_LOCK_FREE unspecified
51e8d8bef9SDimitry Andric#define ATOMIC_CHAR8_T_LOCK_FREE unspecified // C++20
520b57cec5SDimitry Andric#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
530b57cec5SDimitry Andric#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
540b57cec5SDimitry Andric#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
550b57cec5SDimitry Andric#define ATOMIC_SHORT_LOCK_FREE unspecified
560b57cec5SDimitry Andric#define ATOMIC_INT_LOCK_FREE unspecified
570b57cec5SDimitry Andric#define ATOMIC_LONG_LOCK_FREE unspecified
580b57cec5SDimitry Andric#define ATOMIC_LLONG_LOCK_FREE unspecified
590b57cec5SDimitry Andric#define ATOMIC_POINTER_LOCK_FREE unspecified
600b57cec5SDimitry Andric
610b57cec5SDimitry Andrictemplate <class T>
620b57cec5SDimitry Andricstruct atomic
630b57cec5SDimitry Andric{
645ffd83dbSDimitry Andric    using value_type = T;
655ffd83dbSDimitry Andric
660b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
670b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
680b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
695ffd83dbSDimitry Andric
70fe6060f1SDimitry Andric    atomic() noexcept = default; // until C++20
71fe6060f1SDimitry Andric    constexpr atomic() noexcept(is_nothrow_default_constructible_v<T>); // since C++20
725ffd83dbSDimitry Andric    constexpr atomic(T desr) noexcept;
735ffd83dbSDimitry Andric    atomic(const atomic&) = delete;
745ffd83dbSDimitry Andric    atomic& operator=(const atomic&) = delete;
755ffd83dbSDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
765ffd83dbSDimitry Andric
770b57cec5SDimitry Andric    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
780b57cec5SDimitry Andric    T load(memory_order m = memory_order_seq_cst) const noexcept;
790b57cec5SDimitry Andric    operator T() const volatile noexcept;
800b57cec5SDimitry Andric    operator T() const noexcept;
815ffd83dbSDimitry Andric    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
825ffd83dbSDimitry Andric    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
835ffd83dbSDimitry Andric    T operator=(T) volatile noexcept;
845ffd83dbSDimitry Andric    T operator=(T) noexcept;
855ffd83dbSDimitry Andric
860b57cec5SDimitry Andric    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
870b57cec5SDimitry Andric    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
880b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
890b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
900b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
910b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
920b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
930b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
940b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
950b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
960b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
970b57cec5SDimitry Andric    bool compare_exchange_weak(T& expc, T desr,
980b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
990b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
1000b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
1010b57cec5SDimitry Andric    bool compare_exchange_strong(T& expc, T desr,
1020b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
1030b57cec5SDimitry Andric
1045ffd83dbSDimitry Andric    void wait(T, memory_order = memory_order::seq_cst) const volatile noexcept;
1055ffd83dbSDimitry Andric    void wait(T, memory_order = memory_order::seq_cst) const noexcept;
1065ffd83dbSDimitry Andric    void notify_one() volatile noexcept;
1075ffd83dbSDimitry Andric    void notify_one() noexcept;
1085ffd83dbSDimitry Andric    void notify_all() volatile noexcept;
1095ffd83dbSDimitry Andric    void notify_all() noexcept;
1100b57cec5SDimitry Andric};
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andrictemplate <>
1130b57cec5SDimitry Andricstruct atomic<integral>
1140b57cec5SDimitry Andric{
1155ffd83dbSDimitry Andric    using value_type = integral;
116e8d8bef9SDimitry Andric    using difference_type = value_type;
1175ffd83dbSDimitry Andric
1180b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
1190b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
1200b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
1215ffd83dbSDimitry Andric
1225ffd83dbSDimitry Andric    atomic() noexcept = default;
1235ffd83dbSDimitry Andric    constexpr atomic(integral desr) noexcept;
1245ffd83dbSDimitry Andric    atomic(const atomic&) = delete;
1255ffd83dbSDimitry Andric    atomic& operator=(const atomic&) = delete;
1265ffd83dbSDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
1275ffd83dbSDimitry Andric
1280b57cec5SDimitry Andric    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
1290b57cec5SDimitry Andric    integral load(memory_order m = memory_order_seq_cst) const noexcept;
1300b57cec5SDimitry Andric    operator integral() const volatile noexcept;
1310b57cec5SDimitry Andric    operator integral() const noexcept;
1325ffd83dbSDimitry Andric    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
1335ffd83dbSDimitry Andric    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1345ffd83dbSDimitry Andric    integral operator=(integral desr) volatile noexcept;
1355ffd83dbSDimitry Andric    integral operator=(integral desr) noexcept;
1365ffd83dbSDimitry Andric
1370b57cec5SDimitry Andric    integral exchange(integral desr,
1380b57cec5SDimitry Andric                      memory_order m = memory_order_seq_cst) volatile noexcept;
1390b57cec5SDimitry Andric    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
1400b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1410b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
1420b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1430b57cec5SDimitry Andric                               memory_order s, memory_order f) noexcept;
1440b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1450b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
1460b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1470b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
1480b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1490b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
1500b57cec5SDimitry Andric    bool compare_exchange_weak(integral& expc, integral desr,
1510b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
1520b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1530b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
1540b57cec5SDimitry Andric    bool compare_exchange_strong(integral& expc, integral desr,
1550b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
1560b57cec5SDimitry Andric
1575ffd83dbSDimitry Andric    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1580b57cec5SDimitry Andric    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
1595ffd83dbSDimitry Andric    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1600b57cec5SDimitry Andric    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
1615ffd83dbSDimitry Andric    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1620b57cec5SDimitry Andric    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
1635ffd83dbSDimitry Andric    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1640b57cec5SDimitry Andric    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
1655ffd83dbSDimitry Andric    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
1660b57cec5SDimitry Andric    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric    integral operator++(int) volatile noexcept;
1690b57cec5SDimitry Andric    integral operator++(int) noexcept;
1700b57cec5SDimitry Andric    integral operator--(int) volatile noexcept;
1710b57cec5SDimitry Andric    integral operator--(int) noexcept;
1720b57cec5SDimitry Andric    integral operator++() volatile noexcept;
1730b57cec5SDimitry Andric    integral operator++() noexcept;
1740b57cec5SDimitry Andric    integral operator--() volatile noexcept;
1750b57cec5SDimitry Andric    integral operator--() noexcept;
1760b57cec5SDimitry Andric    integral operator+=(integral op) volatile noexcept;
1770b57cec5SDimitry Andric    integral operator+=(integral op) noexcept;
1780b57cec5SDimitry Andric    integral operator-=(integral op) volatile noexcept;
1790b57cec5SDimitry Andric    integral operator-=(integral op) noexcept;
1800b57cec5SDimitry Andric    integral operator&=(integral op) volatile noexcept;
1810b57cec5SDimitry Andric    integral operator&=(integral op) noexcept;
1820b57cec5SDimitry Andric    integral operator|=(integral op) volatile noexcept;
1830b57cec5SDimitry Andric    integral operator|=(integral op) noexcept;
1840b57cec5SDimitry Andric    integral operator^=(integral op) volatile noexcept;
1850b57cec5SDimitry Andric    integral operator^=(integral op) noexcept;
1865ffd83dbSDimitry Andric
1875ffd83dbSDimitry Andric    void wait(integral, memory_order = memory_order::seq_cst) const volatile noexcept;
1885ffd83dbSDimitry Andric    void wait(integral, memory_order = memory_order::seq_cst) const noexcept;
1895ffd83dbSDimitry Andric    void notify_one() volatile noexcept;
1905ffd83dbSDimitry Andric    void notify_one() noexcept;
1915ffd83dbSDimitry Andric    void notify_all() volatile noexcept;
1925ffd83dbSDimitry Andric    void notify_all() noexcept;
1930b57cec5SDimitry Andric};
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andrictemplate <class T>
1960b57cec5SDimitry Andricstruct atomic<T*>
1970b57cec5SDimitry Andric{
1985ffd83dbSDimitry Andric    using value_type = T*;
199e8d8bef9SDimitry Andric    using difference_type = ptrdiff_t;
2005ffd83dbSDimitry Andric
2010b57cec5SDimitry Andric    static constexpr bool is_always_lock_free;
2020b57cec5SDimitry Andric    bool is_lock_free() const volatile noexcept;
2030b57cec5SDimitry Andric    bool is_lock_free() const noexcept;
2045ffd83dbSDimitry Andric
205fe6060f1SDimitry Andric    atomic() noexcept = default; // until C++20
206fe6060f1SDimitry Andric    constexpr atomic() noexcept; // since C++20
2075ffd83dbSDimitry Andric    constexpr atomic(T* desr) noexcept;
2085ffd83dbSDimitry Andric    atomic(const atomic&) = delete;
2095ffd83dbSDimitry Andric    atomic& operator=(const atomic&) = delete;
2105ffd83dbSDimitry Andric    atomic& operator=(const atomic&) volatile = delete;
2115ffd83dbSDimitry Andric
2120b57cec5SDimitry Andric    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
2130b57cec5SDimitry Andric    T* load(memory_order m = memory_order_seq_cst) const noexcept;
2140b57cec5SDimitry Andric    operator T*() const volatile noexcept;
2150b57cec5SDimitry Andric    operator T*() const noexcept;
2165ffd83dbSDimitry Andric    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
2175ffd83dbSDimitry Andric    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2185ffd83dbSDimitry Andric    T* operator=(T*) volatile noexcept;
2195ffd83dbSDimitry Andric    T* operator=(T*) noexcept;
2205ffd83dbSDimitry Andric
2210b57cec5SDimitry Andric    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
2220b57cec5SDimitry Andric    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
2230b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2240b57cec5SDimitry Andric                               memory_order s, memory_order f) volatile noexcept;
2250b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2260b57cec5SDimitry Andric                               memory_order s, memory_order f) noexcept;
2270b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2280b57cec5SDimitry Andric                                 memory_order s, memory_order f) volatile noexcept;
2290b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2300b57cec5SDimitry Andric                                 memory_order s, memory_order f) noexcept;
2310b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2320b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) volatile noexcept;
2330b57cec5SDimitry Andric    bool compare_exchange_weak(T*& expc, T* desr,
2340b57cec5SDimitry Andric                               memory_order m = memory_order_seq_cst) noexcept;
2350b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2360b57cec5SDimitry Andric                                memory_order m = memory_order_seq_cst) volatile noexcept;
2370b57cec5SDimitry Andric    bool compare_exchange_strong(T*& expc, T* desr,
2380b57cec5SDimitry Andric                                 memory_order m = memory_order_seq_cst) noexcept;
2390b57cec5SDimitry Andric    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
2400b57cec5SDimitry Andric    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2410b57cec5SDimitry Andric    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
2420b57cec5SDimitry Andric    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
2430b57cec5SDimitry Andric
2440b57cec5SDimitry Andric    T* operator++(int) volatile noexcept;
2450b57cec5SDimitry Andric    T* operator++(int) noexcept;
2460b57cec5SDimitry Andric    T* operator--(int) volatile noexcept;
2470b57cec5SDimitry Andric    T* operator--(int) noexcept;
2480b57cec5SDimitry Andric    T* operator++() volatile noexcept;
2490b57cec5SDimitry Andric    T* operator++() noexcept;
2500b57cec5SDimitry Andric    T* operator--() volatile noexcept;
2510b57cec5SDimitry Andric    T* operator--() noexcept;
2520b57cec5SDimitry Andric    T* operator+=(ptrdiff_t op) volatile noexcept;
2530b57cec5SDimitry Andric    T* operator+=(ptrdiff_t op) noexcept;
2540b57cec5SDimitry Andric    T* operator-=(ptrdiff_t op) volatile noexcept;
2550b57cec5SDimitry Andric    T* operator-=(ptrdiff_t op) noexcept;
2565ffd83dbSDimitry Andric
2575ffd83dbSDimitry Andric    void wait(T*, memory_order = memory_order::seq_cst) const volatile noexcept;
2585ffd83dbSDimitry Andric    void wait(T*, memory_order = memory_order::seq_cst) const noexcept;
2595ffd83dbSDimitry Andric    void notify_one() volatile noexcept;
2605ffd83dbSDimitry Andric    void notify_one() noexcept;
2615ffd83dbSDimitry Andric    void notify_all() volatile noexcept;
2625ffd83dbSDimitry Andric    void notify_all() noexcept;
2630b57cec5SDimitry Andric};
2640b57cec5SDimitry Andric
2655f757f3fSDimitry Andrictemplate<>
2665f757f3fSDimitry Andricstruct atomic<floating-point-type> {  // since C++20
2675f757f3fSDimitry Andric  using value_type = floating-point-type;
2685f757f3fSDimitry Andric  using difference_type = value_type;
2695f757f3fSDimitry Andric
2705f757f3fSDimitry Andric  static constexpr bool is_always_lock_free = implementation-defined;
2715f757f3fSDimitry Andric  bool is_lock_free() const volatile noexcept;
2725f757f3fSDimitry Andric  bool is_lock_free() const noexcept;
2735f757f3fSDimitry Andric
2745f757f3fSDimitry Andric  constexpr atomic() noexcept;
2755f757f3fSDimitry Andric  constexpr atomic(floating-point-type) noexcept;
2765f757f3fSDimitry Andric  atomic(const atomic&) = delete;
2775f757f3fSDimitry Andric  atomic& operator=(const atomic&) = delete;
2785f757f3fSDimitry Andric  atomic& operator=(const atomic&) volatile = delete;
2795f757f3fSDimitry Andric
2805f757f3fSDimitry Andric  void store(floating-point-type, memory_order = memory_order::seq_cst) volatile noexcept;
2815f757f3fSDimitry Andric  void store(floating-point-type, memory_order = memory_order::seq_cst) noexcept;
2825f757f3fSDimitry Andric  floating-point-type operator=(floating-point-type) volatile noexcept;
2835f757f3fSDimitry Andric  floating-point-type operator=(floating-point-type) noexcept;
2845f757f3fSDimitry Andric  floating-point-type load(memory_order = memory_order::seq_cst) volatile noexcept;
2855f757f3fSDimitry Andric  floating-point-type load(memory_order = memory_order::seq_cst) noexcept;
2865f757f3fSDimitry Andric  operator floating-point-type() volatile noexcept;
2875f757f3fSDimitry Andric  operator floating-point-type() noexcept;
2885f757f3fSDimitry Andric
2895f757f3fSDimitry Andric  floating-point-type exchange(floating-point-type,
2905f757f3fSDimitry Andric                               memory_order = memory_order::seq_cst) volatile noexcept;
2915f757f3fSDimitry Andric  floating-point-type exchange(floating-point-type,
2925f757f3fSDimitry Andric                               memory_order = memory_order::seq_cst) noexcept;
2935f757f3fSDimitry Andric  bool compare_exchange_weak(floating-point-type&, floating-point-type,
2945f757f3fSDimitry Andric                             memory_order, memory_order) volatile noexcept;
2955f757f3fSDimitry Andric  bool compare_exchange_weak(floating-point-type&, floating-point-type,
2965f757f3fSDimitry Andric                             memory_order, memory_order) noexcept;
2975f757f3fSDimitry Andric  bool compare_exchange_strong(floating-point-type&, floating-point-type,
2985f757f3fSDimitry Andric                               memory_order, memory_order) volatile noexcept;
2995f757f3fSDimitry Andric  bool compare_exchange_strong(floating-point-type&, floating-point-type,
3005f757f3fSDimitry Andric                               memory_order, memory_order) noexcept;
3015f757f3fSDimitry Andric  bool compare_exchange_weak(floating-point-type&, floating-point-type,
3025f757f3fSDimitry Andric                             memory_order = memory_order::seq_cst) volatile noexcept;
3035f757f3fSDimitry Andric  bool compare_exchange_weak(floating-point-type&, floating-point-type,
3045f757f3fSDimitry Andric                             memory_order = memory_order::seq_cst) noexcept;
3055f757f3fSDimitry Andric  bool compare_exchange_strong(floating-point-type&, floating-point-type,
3065f757f3fSDimitry Andric                               memory_order = memory_order::seq_cst) volatile noexcept;
3075f757f3fSDimitry Andric  bool compare_exchange_strong(floating-point-type&, floating-point-type,
3085f757f3fSDimitry Andric                               memory_order = memory_order::seq_cst) noexcept;
3095f757f3fSDimitry Andric
3105f757f3fSDimitry Andric  floating-point-type fetch_add(floating-point-type,
3115f757f3fSDimitry Andric                                memory_order = memory_order::seq_cst) volatile noexcept;
3125f757f3fSDimitry Andric  floating-point-type fetch_add(floating-point-type,
3135f757f3fSDimitry Andric                                memory_order = memory_order::seq_cst) noexcept;
3145f757f3fSDimitry Andric  floating-point-type fetch_sub(floating-point-type,
3155f757f3fSDimitry Andric                                memory_order = memory_order::seq_cst) volatile noexcept;
3165f757f3fSDimitry Andric  floating-point-type fetch_sub(floating-point-type,
3175f757f3fSDimitry Andric                                memory_order = memory_order::seq_cst) noexcept;
3185f757f3fSDimitry Andric
3195f757f3fSDimitry Andric  floating-point-type operator+=(floating-point-type) volatile noexcept;
3205f757f3fSDimitry Andric  floating-point-type operator+=(floating-point-type) noexcept;
3215f757f3fSDimitry Andric  floating-point-type operator-=(floating-point-type) volatile noexcept;
3225f757f3fSDimitry Andric  floating-point-type operator-=(floating-point-type) noexcept;
3235f757f3fSDimitry Andric
3245f757f3fSDimitry Andric  void wait(floating-point-type, memory_order = memory_order::seq_cst) const volatile noexcept;
3255f757f3fSDimitry Andric  void wait(floating-point-type, memory_order = memory_order::seq_cst) const noexcept;
3265f757f3fSDimitry Andric  void notify_one() volatile noexcept;
3275f757f3fSDimitry Andric  void notify_one() noexcept;
3285f757f3fSDimitry Andric  void notify_all() volatile noexcept;
3295f757f3fSDimitry Andric  void notify_all() noexcept;
3305f757f3fSDimitry Andric};
3310b57cec5SDimitry Andric
332349cc55cSDimitry Andric// [atomics.nonmembers], non-member functions
3330b57cec5SDimitry Andrictemplate<class T>
334349cc55cSDimitry Andric  bool atomic_is_lock_free(const volatile atomic<T>*) noexcept;
335349cc55cSDimitry Andrictemplate<class T>
336349cc55cSDimitry Andric  bool atomic_is_lock_free(const atomic<T>*) noexcept;
337349cc55cSDimitry Andrictemplate<class T>
338349cc55cSDimitry Andric  void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept;
339349cc55cSDimitry Andrictemplate<class T>
340349cc55cSDimitry Andric  void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept;
341349cc55cSDimitry Andrictemplate<class T>
342349cc55cSDimitry Andric  void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type,
343349cc55cSDimitry Andric                             memory_order) noexcept;
344349cc55cSDimitry Andrictemplate<class T>
345349cc55cSDimitry Andric  void atomic_store_explicit(atomic<T>*, atomic<T>::value_type,
346349cc55cSDimitry Andric                             memory_order) noexcept;
347349cc55cSDimitry Andrictemplate<class T>
348349cc55cSDimitry Andric  T atomic_load(const volatile atomic<T>*) noexcept;
349349cc55cSDimitry Andrictemplate<class T>
350349cc55cSDimitry Andric  T atomic_load(const atomic<T>*) noexcept;
351349cc55cSDimitry Andrictemplate<class T>
352349cc55cSDimitry Andric  T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept;
353349cc55cSDimitry Andrictemplate<class T>
354349cc55cSDimitry Andric  T atomic_load_explicit(const atomic<T>*, memory_order) noexcept;
355349cc55cSDimitry Andrictemplate<class T>
356349cc55cSDimitry Andric  T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept;
357349cc55cSDimitry Andrictemplate<class T>
358349cc55cSDimitry Andric  T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept;
359349cc55cSDimitry Andrictemplate<class T>
360349cc55cSDimitry Andric  T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type,
361349cc55cSDimitry Andric                             memory_order) noexcept;
362349cc55cSDimitry Andrictemplate<class T>
363349cc55cSDimitry Andric  T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type,
364349cc55cSDimitry Andric                             memory_order) noexcept;
365349cc55cSDimitry Andrictemplate<class T>
366349cc55cSDimitry Andric  bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*,
367349cc55cSDimitry Andric                                    atomic<T>::value_type) noexcept;
368349cc55cSDimitry Andrictemplate<class T>
369349cc55cSDimitry Andric  bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*,
370349cc55cSDimitry Andric                                    atomic<T>::value_type) noexcept;
371349cc55cSDimitry Andrictemplate<class T>
372349cc55cSDimitry Andric  bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*,
373349cc55cSDimitry Andric                                      atomic<T>::value_type) noexcept;
374349cc55cSDimitry Andrictemplate<class T>
375349cc55cSDimitry Andric  bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*,
376349cc55cSDimitry Andric                                      atomic<T>::value_type) noexcept;
377349cc55cSDimitry Andrictemplate<class T>
378349cc55cSDimitry Andric  bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*,
379349cc55cSDimitry Andric                                             atomic<T>::value_type,
380349cc55cSDimitry Andric                                             memory_order, memory_order) noexcept;
381349cc55cSDimitry Andrictemplate<class T>
382349cc55cSDimitry Andric  bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*,
383349cc55cSDimitry Andric                                             atomic<T>::value_type,
384349cc55cSDimitry Andric                                             memory_order, memory_order) noexcept;
385349cc55cSDimitry Andrictemplate<class T>
386349cc55cSDimitry Andric  bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*,
387349cc55cSDimitry Andric                                               atomic<T>::value_type,
388349cc55cSDimitry Andric                                               memory_order, memory_order) noexcept;
389349cc55cSDimitry Andrictemplate<class T>
390349cc55cSDimitry Andric  bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*,
391349cc55cSDimitry Andric                                               atomic<T>::value_type,
392349cc55cSDimitry Andric                                               memory_order, memory_order) noexcept;
3930b57cec5SDimitry Andric
3940b57cec5SDimitry Andrictemplate<class T>
395349cc55cSDimitry Andric  T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
396349cc55cSDimitry Andrictemplate<class T>
397349cc55cSDimitry Andric  T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept;
398349cc55cSDimitry Andrictemplate<class T>
399349cc55cSDimitry Andric  T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type,
400349cc55cSDimitry Andric                              memory_order) noexcept;
401349cc55cSDimitry Andrictemplate<class T>
402349cc55cSDimitry Andric  T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type,
403349cc55cSDimitry Andric                              memory_order) noexcept;
404349cc55cSDimitry Andrictemplate<class T>
405349cc55cSDimitry Andric  T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept;
406349cc55cSDimitry Andrictemplate<class T>
407349cc55cSDimitry Andric  T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept;
408349cc55cSDimitry Andrictemplate<class T>
409349cc55cSDimitry Andric  T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type,
410349cc55cSDimitry Andric                              memory_order) noexcept;
411349cc55cSDimitry Andrictemplate<class T>
412349cc55cSDimitry Andric  T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type,
413349cc55cSDimitry Andric                              memory_order) noexcept;
414349cc55cSDimitry Andrictemplate<class T>
415349cc55cSDimitry Andric  T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept;
416349cc55cSDimitry Andrictemplate<class T>
417349cc55cSDimitry Andric  T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept;
418349cc55cSDimitry Andrictemplate<class T>
419349cc55cSDimitry Andric  T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type,
420349cc55cSDimitry Andric                              memory_order) noexcept;
421349cc55cSDimitry Andrictemplate<class T>
422349cc55cSDimitry Andric  T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type,
423349cc55cSDimitry Andric                              memory_order) noexcept;
424349cc55cSDimitry Andrictemplate<class T>
425349cc55cSDimitry Andric  T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept;
426349cc55cSDimitry Andrictemplate<class T>
427349cc55cSDimitry Andric  T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept;
428349cc55cSDimitry Andrictemplate<class T>
429349cc55cSDimitry Andric  T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type,
430349cc55cSDimitry Andric                             memory_order) noexcept;
431349cc55cSDimitry Andrictemplate<class T>
432349cc55cSDimitry Andric  T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type,
433349cc55cSDimitry Andric                             memory_order) noexcept;
434349cc55cSDimitry Andrictemplate<class T>
435349cc55cSDimitry Andric  T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept;
436349cc55cSDimitry Andrictemplate<class T>
437349cc55cSDimitry Andric  T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept;
438349cc55cSDimitry Andrictemplate<class T>
439349cc55cSDimitry Andric  T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type,
440349cc55cSDimitry Andric                              memory_order) noexcept;
441349cc55cSDimitry Andrictemplate<class T>
442349cc55cSDimitry Andric  T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type,
443349cc55cSDimitry Andric                              memory_order) noexcept;
4440b57cec5SDimitry Andric
4450b57cec5SDimitry Andrictemplate<class T>
446bdd1243dSDimitry Andric  void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type) noexcept;
4470b57cec5SDimitry Andrictemplate<class T>
448bdd1243dSDimitry Andric  void atomic_wait(const atomic<T>*, atomic<T>::value_type) noexcept;
4490b57cec5SDimitry Andrictemplate<class T>
450349cc55cSDimitry Andric  void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type,
451bdd1243dSDimitry Andric                            memory_order) noexcept;
4520b57cec5SDimitry Andrictemplate<class T>
453349cc55cSDimitry Andric  void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type,
454bdd1243dSDimitry Andric                            memory_order) noexcept;
4550b57cec5SDimitry Andrictemplate<class T>
456bdd1243dSDimitry Andric  void atomic_notify_one(volatile atomic<T>*) noexcept;
4570b57cec5SDimitry Andrictemplate<class T>
458bdd1243dSDimitry Andric  void atomic_notify_one(atomic<T>*) noexcept;
4590b57cec5SDimitry Andrictemplate<class T>
460bdd1243dSDimitry Andric  void atomic_notify_all(volatile atomic<T>*) noexcept;
4610b57cec5SDimitry Andrictemplate<class T>
462bdd1243dSDimitry Andric  void atomic_notify_all(atomic<T>*) noexcept;
4630b57cec5SDimitry Andric
4640b57cec5SDimitry Andric// Atomics for standard typedef types
4650b57cec5SDimitry Andric
4660b57cec5SDimitry Andrictypedef atomic<bool>               atomic_bool;
4670b57cec5SDimitry Andrictypedef atomic<char>               atomic_char;
4680b57cec5SDimitry Andrictypedef atomic<signed char>        atomic_schar;
4690b57cec5SDimitry Andrictypedef atomic<unsigned char>      atomic_uchar;
4700b57cec5SDimitry Andrictypedef atomic<short>              atomic_short;
4710b57cec5SDimitry Andrictypedef atomic<unsigned short>     atomic_ushort;
4720b57cec5SDimitry Andrictypedef atomic<int>                atomic_int;
4730b57cec5SDimitry Andrictypedef atomic<unsigned int>       atomic_uint;
4740b57cec5SDimitry Andrictypedef atomic<long>               atomic_long;
4750b57cec5SDimitry Andrictypedef atomic<unsigned long>      atomic_ulong;
4760b57cec5SDimitry Andrictypedef atomic<long long>          atomic_llong;
4770b57cec5SDimitry Andrictypedef atomic<unsigned long long> atomic_ullong;
478e8d8bef9SDimitry Andrictypedef atomic<char8_t>            atomic_char8_t; // C++20
4790b57cec5SDimitry Andrictypedef atomic<char16_t>           atomic_char16_t;
4800b57cec5SDimitry Andrictypedef atomic<char32_t>           atomic_char32_t;
4810b57cec5SDimitry Andrictypedef atomic<wchar_t>            atomic_wchar_t;
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andrictypedef atomic<int_least8_t>   atomic_int_least8_t;
4840b57cec5SDimitry Andrictypedef atomic<uint_least8_t>  atomic_uint_least8_t;
4850b57cec5SDimitry Andrictypedef atomic<int_least16_t>  atomic_int_least16_t;
4860b57cec5SDimitry Andrictypedef atomic<uint_least16_t> atomic_uint_least16_t;
4870b57cec5SDimitry Andrictypedef atomic<int_least32_t>  atomic_int_least32_t;
4880b57cec5SDimitry Andrictypedef atomic<uint_least32_t> atomic_uint_least32_t;
4890b57cec5SDimitry Andrictypedef atomic<int_least64_t>  atomic_int_least64_t;
4900b57cec5SDimitry Andrictypedef atomic<uint_least64_t> atomic_uint_least64_t;
4910b57cec5SDimitry Andric
4920b57cec5SDimitry Andrictypedef atomic<int_fast8_t>   atomic_int_fast8_t;
4930b57cec5SDimitry Andrictypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
4940b57cec5SDimitry Andrictypedef atomic<int_fast16_t>  atomic_int_fast16_t;
4950b57cec5SDimitry Andrictypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
4960b57cec5SDimitry Andrictypedef atomic<int_fast32_t>  atomic_int_fast32_t;
4970b57cec5SDimitry Andrictypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
4980b57cec5SDimitry Andrictypedef atomic<int_fast64_t>  atomic_int_fast64_t;
4990b57cec5SDimitry Andrictypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
5000b57cec5SDimitry Andric
5010b57cec5SDimitry Andrictypedef atomic<int8_t>   atomic_int8_t;
5020b57cec5SDimitry Andrictypedef atomic<uint8_t>  atomic_uint8_t;
5030b57cec5SDimitry Andrictypedef atomic<int16_t>  atomic_int16_t;
5040b57cec5SDimitry Andrictypedef atomic<uint16_t> atomic_uint16_t;
5050b57cec5SDimitry Andrictypedef atomic<int32_t>  atomic_int32_t;
5060b57cec5SDimitry Andrictypedef atomic<uint32_t> atomic_uint32_t;
5070b57cec5SDimitry Andrictypedef atomic<int64_t>  atomic_int64_t;
5080b57cec5SDimitry Andrictypedef atomic<uint64_t> atomic_uint64_t;
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andrictypedef atomic<intptr_t>  atomic_intptr_t;
5110b57cec5SDimitry Andrictypedef atomic<uintptr_t> atomic_uintptr_t;
5120b57cec5SDimitry Andrictypedef atomic<size_t>    atomic_size_t;
5130b57cec5SDimitry Andrictypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
5140b57cec5SDimitry Andrictypedef atomic<intmax_t>  atomic_intmax_t;
5150b57cec5SDimitry Andrictypedef atomic<uintmax_t> atomic_uintmax_t;
5160b57cec5SDimitry Andric
5175f757f3fSDimitry Andrictypedef see-below         atomic_signed_lock_free;   // since C++20
5185f757f3fSDimitry Andrictypedef see-below         atomic_unsigned_lock_free; // since C++20
5195f757f3fSDimitry Andric
5205ffd83dbSDimitry Andric// flag type and operations
5215ffd83dbSDimitry Andric
5225ffd83dbSDimitry Andrictypedef struct atomic_flag
5235ffd83dbSDimitry Andric{
524fe6060f1SDimitry Andric    atomic_flag() noexcept = default; // until C++20
525fe6060f1SDimitry Andric    constexpr atomic_flag() noexcept; // since C++20
5265ffd83dbSDimitry Andric    atomic_flag(const atomic_flag&) = delete;
5275ffd83dbSDimitry Andric    atomic_flag& operator=(const atomic_flag&) = delete;
5285ffd83dbSDimitry Andric    atomic_flag& operator=(const atomic_flag&) volatile = delete;
5295ffd83dbSDimitry Andric
5305ffd83dbSDimitry Andric    bool test(memory_order m = memory_order_seq_cst) volatile noexcept;
5315ffd83dbSDimitry Andric    bool test(memory_order m = memory_order_seq_cst) noexcept;
5325ffd83dbSDimitry Andric    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
5335ffd83dbSDimitry Andric    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
5345ffd83dbSDimitry Andric    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
5355ffd83dbSDimitry Andric    void clear(memory_order m = memory_order_seq_cst) noexcept;
5365ffd83dbSDimitry Andric
5375ffd83dbSDimitry Andric    void wait(bool, memory_order = memory_order::seq_cst) const volatile noexcept;
5385ffd83dbSDimitry Andric    void wait(bool, memory_order = memory_order::seq_cst) const noexcept;
5395ffd83dbSDimitry Andric    void notify_one() volatile noexcept;
5405ffd83dbSDimitry Andric    void notify_one() noexcept;
5415ffd83dbSDimitry Andric    void notify_all() volatile noexcept;
5425ffd83dbSDimitry Andric    void notify_all() noexcept;
5435ffd83dbSDimitry Andric} atomic_flag;
5445ffd83dbSDimitry Andric
5455ffd83dbSDimitry Andricbool atomic_flag_test(volatile atomic_flag* obj) noexcept;
5465ffd83dbSDimitry Andricbool atomic_flag_test(atomic_flag* obj) noexcept;
5475ffd83dbSDimitry Andricbool atomic_flag_test_explicit(volatile atomic_flag* obj,
5485ffd83dbSDimitry Andric                               memory_order m) noexcept;
5495ffd83dbSDimitry Andricbool atomic_flag_test_explicit(atomic_flag* obj, memory_order m) noexcept;
5505ffd83dbSDimitry Andricbool atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
5515ffd83dbSDimitry Andricbool atomic_flag_test_and_set(atomic_flag* obj) noexcept;
5525ffd83dbSDimitry Andricbool atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
5535ffd83dbSDimitry Andric                                       memory_order m) noexcept;
5545ffd83dbSDimitry Andricbool atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
5555ffd83dbSDimitry Andricvoid atomic_flag_clear(volatile atomic_flag* obj) noexcept;
5565ffd83dbSDimitry Andricvoid atomic_flag_clear(atomic_flag* obj) noexcept;
5575ffd83dbSDimitry Andricvoid atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
5585ffd83dbSDimitry Andricvoid atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
5595ffd83dbSDimitry Andric
5605ffd83dbSDimitry Andricvoid atomic_wait(const volatile atomic_flag* obj, T old) noexcept;
5615ffd83dbSDimitry Andricvoid atomic_wait(const atomic_flag* obj, T old) noexcept;
5625ffd83dbSDimitry Andricvoid atomic_wait_explicit(const volatile atomic_flag* obj, T old, memory_order m) noexcept;
5635ffd83dbSDimitry Andricvoid atomic_wait_explicit(const atomic_flag* obj, T old, memory_order m) noexcept;
5645ffd83dbSDimitry Andricvoid atomic_one(volatile atomic_flag* obj) noexcept;
5655ffd83dbSDimitry Andricvoid atomic_one(atomic_flag* obj) noexcept;
5665ffd83dbSDimitry Andricvoid atomic_all(volatile atomic_flag* obj) noexcept;
5675ffd83dbSDimitry Andricvoid atomic_all(atomic_flag* obj) noexcept;
5685ffd83dbSDimitry Andric
5690b57cec5SDimitry Andric// fences
5700b57cec5SDimitry Andric
5710b57cec5SDimitry Andricvoid atomic_thread_fence(memory_order m) noexcept;
5720b57cec5SDimitry Andricvoid atomic_signal_fence(memory_order m) noexcept;
5730b57cec5SDimitry Andric
5745ffd83dbSDimitry Andric// deprecated
5755ffd83dbSDimitry Andric
5765ffd83dbSDimitry Andrictemplate <class T>
577349cc55cSDimitry Andric  void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept;
5785ffd83dbSDimitry Andric
5795ffd83dbSDimitry Andrictemplate <class T>
580349cc55cSDimitry Andric  void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept;
5815ffd83dbSDimitry Andric
5825ffd83dbSDimitry Andric#define ATOMIC_VAR_INIT(value) see below
5835ffd83dbSDimitry Andric
5845ffd83dbSDimitry Andric#define ATOMIC_FLAG_INIT see below
5855ffd83dbSDimitry Andric
5860b57cec5SDimitry Andric}  // std
5870b57cec5SDimitry Andric
5880b57cec5SDimitry Andric*/
5890b57cec5SDimitry Andric
590*0fca6ea1SDimitry Andric#include <__config>
591*0fca6ea1SDimitry Andric
592*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER < 23 && defined(_LIBCPP_STDATOMIC_H)
593*0fca6ea1SDimitry Andric#  error <atomic> is incompatible with <stdatomic.h> before C++23. Please compile with -std=c++23.
594*0fca6ea1SDimitry Andric#endif
595*0fca6ea1SDimitry Andric
59606c3fb27SDimitry Andric#include <__atomic/aliases.h>
59706c3fb27SDimitry Andric#include <__atomic/atomic.h>
59806c3fb27SDimitry Andric#include <__atomic/atomic_base.h>
59906c3fb27SDimitry Andric#include <__atomic/atomic_flag.h>
60006c3fb27SDimitry Andric#include <__atomic/atomic_init.h>
60106c3fb27SDimitry Andric#include <__atomic/atomic_lock_free.h>
60206c3fb27SDimitry Andric#include <__atomic/atomic_sync.h>
60306c3fb27SDimitry Andric#include <__atomic/check_memory_order.h>
60406c3fb27SDimitry Andric#include <__atomic/contention_t.h>
60506c3fb27SDimitry Andric#include <__atomic/cxx_atomic_impl.h>
60606c3fb27SDimitry Andric#include <__atomic/fence.h>
60706c3fb27SDimitry Andric#include <__atomic/is_always_lock_free.h>
60806c3fb27SDimitry Andric#include <__atomic/kill_dependency.h>
60906c3fb27SDimitry Andric#include <__atomic/memory_order.h>
6100b57cec5SDimitry Andric#include <version>
6110b57cec5SDimitry Andric
612*0fca6ea1SDimitry Andric#if _LIBCPP_STD_VER >= 20
613*0fca6ea1SDimitry Andric#  include <__atomic/atomic_ref.h>
614*0fca6ea1SDimitry Andric#endif
615*0fca6ea1SDimitry Andric
6160b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
6170b57cec5SDimitry Andric#  pragma GCC system_header
6180b57cec5SDimitry Andric#endif
6190b57cec5SDimitry Andric
6200b57cec5SDimitry Andric#ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER
6210b57cec5SDimitry Andric#  error <atomic> is not implemented
6220b57cec5SDimitry Andric#endif
62306c3fb27SDimitry Andric
624bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
625bdd1243dSDimitry Andric#  include <cmath>
626bdd1243dSDimitry Andric#  include <compare>
627*0fca6ea1SDimitry Andric#  include <cstdlib>
62806c3fb27SDimitry Andric#  include <cstring>
629bdd1243dSDimitry Andric#  include <type_traits>
630bdd1243dSDimitry Andric#endif
631bdd1243dSDimitry Andric
6320b57cec5SDimitry Andric#endif // _LIBCPP_ATOMIC
633