atomic revision 241903
150476Speter// -*- C++ -*-
217446Swollman//===--------------------------- atomic -----------------------------------===//
3198948Sru//
4198948Sru//                     The LLVM Compiler Infrastructure
5198948Sru//
617446Swollman// This file is distributed under the University of Illinois Open Source
7101944Sblackend// License. See LICENSE.TXT for details.
817446Swollman//
917446Swollman//===----------------------------------------------------------------------===//
1017446Swollman
1117446Swollman#ifndef _LIBCPP_ATOMIC
1217446Swollman#define _LIBCPP_ATOMIC
1317446Swollman
1417446Swollman/*
1517446Swollman    atomic synopsis
16101944Sblackend
1717446Swollmannamespace std
1868639Snik{
19189767Sru
2017446Swollman// order and consistency
2117446Swollman
2217446Swollmantypedef enum memory_order
2317446Swollman{
24130446Swollman    memory_order_relaxed,
2517446Swollman    memory_order_consume,  // load-consume
2617446Swollman    memory_order_acquire,  // load-acquire
2717446Swollman    memory_order_release,  // store-release
2817446Swollman    memory_order_acq_rel,  // store-release load-acquire
2917446Swollman    memory_order_seq_cst   // store-release load-acquire
3017446Swollman} memory_order;
3117446Swollman
3217446Swollmantemplate <class T> T kill_dependency(T y) noexcept;
3317446Swollman
3417446Swollman// lock-free property
3517446Swollman
3617446Swollman#define ATOMIC_CHAR_LOCK_FREE unspecified
3717446Swollman#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
3817446Swollman#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
3917446Swollman#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
4017446Swollman#define ATOMIC_SHORT_LOCK_FREE unspecified
4117446Swollman#define ATOMIC_INT_LOCK_FREE unspecified
4217446Swollman#define ATOMIC_LONG_LOCK_FREE unspecified
4317446Swollman#define ATOMIC_LLONG_LOCK_FREE unspecified
4417446Swollman
4517446Swollman// flag type and operations
4617446Swollman
4717446Swollmantypedef struct atomic_flag
48197392Sru{
49226283Sedwin    bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
50189767Sru    bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
5117446Swollman    void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
5217446Swollman    void clear(memory_order m = memory_order_seq_cst) noexcept;
5317446Swollman    atomic_flag()  noexcept = default;
5417446Swollman    atomic_flag(const atomic_flag&) = delete;
5517446Swollman    atomic_flag& operator=(const atomic_flag&) = delete;
5617446Swollman    atomic_flag& operator=(const atomic_flag&) volatile = delete;
5717446Swollman} atomic_flag;
5817446Swollman
5917446Swollmanbool
6017446Swollman    atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
6117446Swollman
6217446Swollmanbool
6317446Swollman    atomic_flag_test_and_set(atomic_flag* obj) noexcept;
6417446Swollman
6517446Swollmanbool
6617446Swollman    atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
6717446Swollman                                      memory_order m) noexcept;
6817446Swollman
6917446Swollmanbool
7017446Swollman    atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
7117446Swollman
72189767Sruvoid
73189767Sru    atomic_flag_clear(volatile atomic_flag* obj) noexcept;
7417446Swollman
7517446Swollmanvoid
7617446Swollman    atomic_flag_clear(atomic_flag* obj) noexcept;
7717446Swollman
7817446Swollmanvoid
79222011Suqs    atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
8017446Swollman
8117446Swollmanvoid
8217446Swollman    atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
8317446Swollman
8417446Swollman#define ATOMIC_FLAG_INIT see below
8517446Swollman#define ATOMIC_VAR_INIT(value) see below
86113541Swollman
8717446Swollmantemplate <class T>
8817446Swollmanstruct atomic
8917446Swollman{
9017446Swollman    bool is_lock_free() const volatile noexcept;
9117446Swollman    bool is_lock_free() const noexcept;
9217446Swollman    void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
9317446Swollman    void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
94189767Sru    T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
9517446Swollman    T load(memory_order m = memory_order_seq_cst) const noexcept;
9617446Swollman    operator T() const volatile noexcept;
9717446Swollman    operator T() const noexcept;
9817446Swollman    T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
9917446Swollman    T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
10017446Swollman    bool compare_exchange_weak(T& expc, T desr,
10117446Swollman                               memory_order s, memory_order f) volatile noexcept;
10217446Swollman    bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
10317446Swollman    bool compare_exchange_strong(T& expc, T desr,
10417446Swollman                                 memory_order s, memory_order f) volatile noexcept;
10517446Swollman    bool compare_exchange_strong(T& expc, T desr,
10617446Swollman                                 memory_order s, memory_order f) noexcept;
10717446Swollman    bool compare_exchange_weak(T& expc, T desr,
10817446Swollman                               memory_order m = memory_order_seq_cst) volatile noexcept;
10917446Swollman    bool compare_exchange_weak(T& expc, T desr,
11017446Swollman                               memory_order m = memory_order_seq_cst) noexcept;
11117446Swollman    bool compare_exchange_strong(T& expc, T desr,
11217446Swollman                                memory_order m = memory_order_seq_cst) volatile noexcept;
11317446Swollman    bool compare_exchange_strong(T& expc, T desr,
114158863Swollman                                 memory_order m = memory_order_seq_cst) noexcept;
11517446Swollman
11617446Swollman    atomic() noexcept = default;
11717446Swollman    constexpr atomic(T desr) noexcept;
11817446Swollman    atomic(const atomic&) = delete;
119189767Sru    atomic& operator=(const atomic&) = delete;
12017446Swollman    atomic& operator=(const atomic&) volatile = delete;
12117446Swollman    T operator=(T) volatile noexcept;
12217446Swollman    T operator=(T) noexcept;
12317446Swollman};
12417446Swollman
12517446Swollmantemplate <>
126189767Srustruct atomic<integral>
12717446Swollman{
12817446Swollman    bool is_lock_free() const volatile noexcept;
129158863Swollman    bool is_lock_free() const noexcept;
13017446Swollman    void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
13117446Swollman    void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
13217446Swollman    integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
13317446Swollman    integral load(memory_order m = memory_order_seq_cst) const noexcept;
134158863Swollman    operator integral() const volatile noexcept;
13517446Swollman    operator integral() const noexcept;
13617446Swollman    integral exchange(integral desr,
13717446Swollman                      memory_order m = memory_order_seq_cst) volatile noexcept;
13817446Swollman    integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
139189767Sru    bool compare_exchange_weak(integral& expc, integral desr,
140189767Sru                               memory_order s, memory_order f) volatile noexcept;
14117446Swollman    bool compare_exchange_weak(integral& expc, integral desr,
14217446Swollman                               memory_order s, memory_order f) noexcept;
14317446Swollman    bool compare_exchange_strong(integral& expc, integral desr,
14417446Swollman                                 memory_order s, memory_order f) volatile noexcept;
14517446Swollman    bool compare_exchange_strong(integral& expc, integral desr,
14617446Swollman                                 memory_order s, memory_order f) noexcept;
14717446Swollman    bool compare_exchange_weak(integral& expc, integral desr,
14817446Swollman                               memory_order m = memory_order_seq_cst) volatile noexcept;
14917446Swollman    bool compare_exchange_weak(integral& expc, integral desr,
15017446Swollman                               memory_order m = memory_order_seq_cst) noexcept;
15117446Swollman    bool compare_exchange_strong(integral& expc, integral desr,
15297614Swollman                                memory_order m = memory_order_seq_cst) volatile noexcept;
153189767Sru    bool compare_exchange_strong(integral& expc, integral desr,
15417446Swollman                                 memory_order m = memory_order_seq_cst) noexcept;
15517446Swollman
15617446Swollman    integral
15717446Swollman        fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
15817446Swollman    integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
15917446Swollman    integral
16017446Swollman        fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
16117446Swollman    integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
16217446Swollman    integral
16317446Swollman        fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
16417446Swollman    integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
16517446Swollman    integral
166189767Sru        fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
167189767Sru    integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
16817446Swollman    integral
16917446Swollman        fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
170163477Sru    integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
17117446Swollman
17217446Swollman    atomic() noexcept = default;
17317446Swollman    constexpr atomic(integral desr) noexcept;
17417446Swollman    atomic(const atomic&) = delete;
17517446Swollman    atomic& operator=(const atomic&) = delete;
17617446Swollman    atomic& operator=(const atomic&) volatile = delete;
17717446Swollman    integral operator=(integral desr) volatile noexcept;
17817446Swollman    integral operator=(integral desr) noexcept;
17917446Swollman
18017446Swollman    integral operator++(int) volatile noexcept;
18117446Swollman    integral operator++(int) noexcept;
18217446Swollman    integral operator--(int) volatile noexcept;
18317446Swollman    integral operator--(int) noexcept;
18417446Swollman    integral operator++() volatile noexcept;
18517446Swollman    integral operator++() noexcept;
18617446Swollman    integral operator--() volatile noexcept;
18717446Swollman    integral operator--() noexcept;
18817446Swollman    integral operator+=(integral op) volatile noexcept;
18917446Swollman    integral operator+=(integral op) noexcept;
19017446Swollman    integral operator-=(integral op) volatile noexcept;
191189767Sru    integral operator-=(integral op) noexcept;
19217446Swollman    integral operator&=(integral op) volatile noexcept;
193189767Sru    integral operator&=(integral op) noexcept;
19417446Swollman    integral operator|=(integral op) volatile noexcept;
19517446Swollman    integral operator|=(integral op) noexcept;
19617446Swollman    integral operator^=(integral op) volatile noexcept;
19717446Swollman    integral operator^=(integral op) noexcept;
19817446Swollman};
19917446Swollman
20017446Swollmantemplate <class T>
20117446Swollmanstruct atomic<T*>
20217446Swollman{
20390196Swollman    bool is_lock_free() const volatile noexcept;
20417446Swollman    bool is_lock_free() const noexcept;
20517446Swollman    void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
206174241Sedwin    void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
20717446Swollman    T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
20817446Swollman    T* load(memory_order m = memory_order_seq_cst) const noexcept;
209222014Sru    operator T*() const volatile noexcept;
21017446Swollman    operator T*() const noexcept;
21117446Swollman    T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
21217446Swollman    T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
21317446Swollman    bool compare_exchange_weak(T*& expc, T* desr,
21417446Swollman                               memory_order s, memory_order f) volatile noexcept;
21517446Swollman    bool compare_exchange_weak(T*& expc, T* desr,
216163477Sru                               memory_order s, memory_order f) noexcept;
21717446Swollman    bool compare_exchange_strong(T*& expc, T* desr,
21817446Swollman                                 memory_order s, memory_order f) volatile noexcept;
21917446Swollman    bool compare_exchange_strong(T*& expc, T* desr,
220222011Suqs                                 memory_order s, memory_order f) noexcept;
22117446Swollman    bool compare_exchange_weak(T*& expc, T* desr,
22217446Swollman                               memory_order m = memory_order_seq_cst) volatile noexcept;
22317446Swollman    bool compare_exchange_weak(T*& expc, T* desr,
22417446Swollman                               memory_order m = memory_order_seq_cst) noexcept;
22517446Swollman    bool compare_exchange_strong(T*& expc, T* desr,
22617446Swollman                                memory_order m = memory_order_seq_cst) volatile noexcept;
227226283Sedwin    bool compare_exchange_strong(T*& expc, T* desr,
22817446Swollman                                 memory_order m = memory_order_seq_cst) noexcept;
22917446Swollman    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
230222011Suqs    T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
231189767Sru    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
232226283Sedwin    T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
23317446Swollman
234189767Sru    atomic() noexcept = default;
23517446Swollman    constexpr atomic(T* desr) noexcept;
23617446Swollman    atomic(const atomic&) = delete;
23717446Swollman    atomic& operator=(const atomic&) = delete;
23817446Swollman    atomic& operator=(const atomic&) volatile = delete;
239198948Sru
24017446Swollman    T* operator=(T*) volatile noexcept;
241189767Sru    T* operator=(T*) noexcept;
24217446Swollman    T* operator++(int) volatile noexcept;
24317446Swollman    T* operator++(int) noexcept;
24417446Swollman    T* operator--(int) volatile noexcept;
24517446Swollman    T* operator--(int) noexcept;
24617446Swollman    T* operator++() volatile noexcept;
24717446Swollman    T* operator++() noexcept;
24817446Swollman    T* operator--() volatile noexcept;
24917446Swollman    T* operator--() noexcept;
25017446Swollman    T* operator+=(ptrdiff_t op) volatile noexcept;
25117446Swollman    T* operator+=(ptrdiff_t op) noexcept;
25217446Swollman    T* operator-=(ptrdiff_t op) volatile noexcept;
25317446Swollman    T* operator-=(ptrdiff_t op) noexcept;
25417446Swollman};
25517446Swollman
25617446Swollman
25717446Swollmantemplate <class T>
25817446Swollman    bool
25917446Swollman    atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
26017446Swollman
261189767Srutemplate <class T>
262197392Sru    bool
26317446Swollman    atomic_is_lock_free(const atomic<T>* obj) noexcept;
264189767Sru
265189767Srutemplate <class T>
266189767Sru    void
26717446Swollman    atomic_init(volatile atomic<T>* obj, T desr) noexcept;
26817446Swollman
26917446Swollmantemplate <class T>
27017446Swollman    void
27117446Swollman    atomic_init(atomic<T>* obj, T desr) noexcept;
27217446Swollman
27317446Swollmantemplate <class T>
27417446Swollman    void
27517446Swollman    atomic_store(volatile atomic<T>* obj, T desr) noexcept;
27617446Swollman
27717446Swollmantemplate <class T>
27817446Swollman    void
27917446Swollman    atomic_store(atomic<T>* obj, T desr) noexcept;
28017446Swollman
28117446Swollmantemplate <class T>
28217446Swollman    void
28317446Swollman    atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
28417446Swollman
28517446Swollmantemplate <class T>
28617446Swollman    void
28717446Swollman    atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
28817446Swollman
28917446Swollmantemplate <class T>
29017446Swollman    T
29117446Swollman    atomic_load(const volatile atomic<T>* obj) noexcept;
29217446Swollman
29317446Swollmantemplate <class T>
29417446Swollman    T
29517446Swollman    atomic_load(const atomic<T>* obj) noexcept;
29617446Swollman
29717446Swollmantemplate <class T>
29817446Swollman    T
29917446Swollman    atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
30017446Swollman
30117446Swollmantemplate <class T>
30217446Swollman    T
30317446Swollman    atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
30417446Swollman
30517446Swollmantemplate <class T>
30617446Swollman    T
30717446Swollman    atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
30817446Swollman
30917446Swollmantemplate <class T>
31017446Swollman    T
31117446Swollman    atomic_exchange(atomic<T>* obj, T desr) noexcept;
31217446Swollman
31317446Swollmantemplate <class T>
31417446Swollman    T
31517446Swollman    atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
31617446Swollman
31717446Swollmantemplate <class T>
31817446Swollman    T
31917446Swollman    atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
32017446Swollman
32117446Swollmantemplate <class T>
32217446Swollman    bool
32317446Swollman    atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
32417446Swollman
32517446Swollmantemplate <class T>
32617446Swollman    bool
32717446Swollman    atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
32817446Swollman
32917446Swollmantemplate <class T>
33017446Swollman    bool
33117446Swollman    atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
33217446Swollman
33317446Swollmantemplate <class T>
33417446Swollman    bool
33517446Swollman    atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
33617446Swollman
33717446Swollmantemplate <class T>
33817446Swollman    bool
33917446Swollman    atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
34017446Swollman                                          T desr,
34117446Swollman                                          memory_order s, memory_order f) noexcept;
34217446Swollman
34317446Swollmantemplate <class T>
34417446Swollman    bool
34517446Swollman    atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
34617446Swollman                                          memory_order s, memory_order f) noexcept;
34717446Swollman
34817446Swollmantemplate <class T>
34917446Swollman    bool
35017446Swollman    atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
35117446Swollman                                            T* expc, T desr,
35217446Swollman                                            memory_order s, memory_order f) noexcept;
35317446Swollman
35417446Swollmantemplate <class T>
35517446Swollman    bool
35617446Swollman    atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
35717446Swollman                                            T desr,
35817446Swollman                                            memory_order s, memory_order f) noexcept;
35917446Swollman
36017446Swollmantemplate <class Integral>
36117446Swollman    Integral
36217446Swollman    atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
36317446Swollman
36417446Swollmantemplate <class Integral>
36517446Swollman    Integral
36617446Swollman    atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
36717446Swollman
36817446Swollmantemplate <class Integral>
36917446Swollman    Integral
37017446Swollman    atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
37117446Swollman                              memory_order m) noexcept;
37217446Swollmantemplate <class Integral>
37317446Swollman    Integral
37417446Swollman    atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
37517446Swollman                              memory_order m) noexcept;
37617446Swollmantemplate <class Integral>
37717446Swollman    Integral
37817446Swollman    atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
37917446Swollman
38017446Swollmantemplate <class Integral>
38117446Swollman    Integral
38217446Swollman    atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
38317446Swollman
38417446Swollmantemplate <class Integral>
38517446Swollman    Integral
38617446Swollman    atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
38717446Swollman                              memory_order m) noexcept;
38817446Swollmantemplate <class Integral>
38917446Swollman    Integral
39017446Swollman    atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
39117446Swollman                              memory_order m) noexcept;
39217446Swollmantemplate <class Integral>
39317446Swollman    Integral
39417446Swollman    atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
39517446Swollman
39617446Swollmantemplate <class Integral>
39717446Swollman    Integral
39817446Swollman    atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
39917446Swollman
40017446Swollmantemplate <class Integral>
401222010Suqs    Integral
40217446Swollman    atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
40317446Swollman                              memory_order m) noexcept;
40417446Swollmantemplate <class Integral>
40517446Swollman    Integral
40617446Swollman    atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
40717446Swollman                              memory_order m) noexcept;
40817446Swollmantemplate <class Integral>
40917446Swollman    Integral
41017446Swollman    atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
41117446Swollman
41217446Swollmantemplate <class Integral>
41317446Swollman    Integral
41417446Swollman    atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
41517446Swollman
41617446Swollmantemplate <class Integral>
41717446Swollman    Integral
41817446Swollman    atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
41917446Swollman                             memory_order m) noexcept;
42017446Swollmantemplate <class Integral>
42117446Swollman    Integral
42217446Swollman    atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
42317446Swollman                             memory_order m) noexcept;
42417446Swollmantemplate <class Integral>
42517446Swollman    Integral
42617446Swollman    atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
42717446Swollman
42817446Swollmantemplate <class Integral>
42917446Swollman    Integral
43017446Swollman    atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
43117446Swollman
432222010Suqstemplate <class Integral>
43317446Swollman    Integral
43417446Swollman    atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
43517446Swollman                              memory_order m) noexcept;
436222010Suqstemplate <class Integral>
43717446Swollman    Integral
43817446Swollman    atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
43917446Swollman                              memory_order m) noexcept;
440222010Suqs
44117446Swollmantemplate <class T>
44217446Swollman    T*
44317446Swollman    atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
44417446Swollman
44517446Swollmantemplate <class T>
44617446Swollman    T*
44717446Swollman    atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
44817446Swollman
44917446Swollmantemplate <class T>
45017446Swollman    T*
451174014Skeramida    atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
452174014Skeramida                              memory_order m) noexcept;
45317446Swollmantemplate <class T>
45417446Swollman    T*
45517446Swollman    atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
456222010Suqs
45717446Swollmantemplate <class T>
458222010Suqs    T*
459222010Suqs    atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
46017446Swollman
46117446Swollmantemplate <class T>
46217446Swollman    T*
463222010Suqs    atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
46417446Swollman
46517446Swollmantemplate <class T>
46617446Swollman    T*
467222010Suqs    atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
46817446Swollman                              memory_order m) noexcept;
46917446Swollmantemplate <class T>
47017446Swollman    T*
47117446Swollman    atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
472222010Suqs
47317446Swollman// Atomics for standard typedef types
47417446Swollman
47530812Swollmantypedef atomic<char>               atomic_char;
47630812Swollmantypedef atomic<signed char>        atomic_schar;
47730812Swollmantypedef atomic<unsigned char>      atomic_uchar;
47830812Swollmantypedef atomic<short>              atomic_short;
47990196Swollmantypedef atomic<unsigned short>     atomic_ushort;
48090196Swollmantypedef atomic<int>                atomic_int;
48190196Swollmantypedef atomic<unsigned int>       atomic_uint;
48290196Swollmantypedef atomic<long>               atomic_long;
48397614Swollmantypedef atomic<unsigned long>      atomic_ulong;
48497614Swollmantypedef atomic<long long>          atomic_llong;
48597614Swollmantypedef atomic<unsigned long long> atomic_ullong;
48697614Swollmantypedef atomic<char16_t>           atomic_char16_t;
48797614Swollmantypedef atomic<char32_t>           atomic_char32_t;
48897614Swollmantypedef atomic<wchar_t>            atomic_wchar_t;
48997614Swollman
49097614Swollmantypedef atomic<int_least8_t>   atomic_int_least8_t;
49197614Swollmantypedef atomic<uint_least8_t>  atomic_uint_least8_t;
49297614Swollmantypedef atomic<int_least16_t>  atomic_int_least16_t;
49397614Swollmantypedef atomic<uint_least16_t> atomic_uint_least16_t;
49497614Swollmantypedef atomic<int_least32_t>  atomic_int_least32_t;
495113541Swollmantypedef atomic<uint_least32_t> atomic_uint_least32_t;
496113541Swollmantypedef atomic<int_least64_t>  atomic_int_least64_t;
497113541Swollmantypedef atomic<uint_least64_t> atomic_uint_least64_t;
498113541Swollman
499113541Swollmantypedef atomic<int_fast8_t>   atomic_int_fast8_t;
500113541Swollmantypedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
501113541Swollmantypedef atomic<int_fast16_t>  atomic_int_fast16_t;
502118970Swollmantypedef atomic<uint_fast16_t> atomic_uint_fast16_t;
503118970Swollmantypedef atomic<int_fast32_t>  atomic_int_fast32_t;
504118970Swollmantypedef atomic<uint_fast32_t> atomic_uint_fast32_t;
505130446Swollmantypedef atomic<int_fast64_t>  atomic_int_fast64_t;
506130446Swollmantypedef atomic<uint_fast64_t> atomic_uint_fast64_t;
507130446Swollman
508130446Swollmantypedef atomic<intptr_t>  atomic_intptr_t;
509158863Swollmantypedef atomic<uintptr_t> atomic_uintptr_t;
510130446Swollmantypedef atomic<size_t>    atomic_size_t;
511130446Swollmantypedef atomic<ptrdiff_t> atomic_ptrdiff_t;
512130446Swollmantypedef atomic<intmax_t>  atomic_intmax_t;
513130446Swollmantypedef atomic<uintmax_t> atomic_uintmax_t;
514130446Swollman
515130446Swollman// fences
516130446Swollman
517158863Swollmanvoid atomic_thread_fence(memory_order m) noexcept;
518158863Swollmanvoid atomic_signal_fence(memory_order m) noexcept;
519158863Swollman
520158863Swollman}  // std
521163477Sru
522163477Sru*/
523163477Sru
524174241Sedwin#include <__config>
525174241Sedwin#include <cstddef>
526174241Sedwin#include <cstdint>
527197392Sru#include <type_traits>
528197392Sru
529197392Sru#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
530197392Sru#pragma GCC system_header
531197392Sru#endif
532197392Sru
533197392Sru_LIBCPP_BEGIN_NAMESPACE_STD
534197392Sru
535197392Sru#if !__has_feature(cxx_atomic)
536197392Sru#error <atomic> is not implemented
537197392Sru#else
538197392Sru
539197392Srutypedef enum memory_order
540197392Sru{
541197392Sru    memory_order_relaxed, memory_order_consume, memory_order_acquire,
542197392Sru    memory_order_release, memory_order_acq_rel, memory_order_seq_cst
543222011Suqs} memory_order;
544222011Suqs
545222011Suqstemplate <class _Tp>
546222011Suqsinline _LIBCPP_INLINE_VISIBILITY
547222011Suqs_Tp
548222011Suqskill_dependency(_Tp __y) _NOEXCEPT
549222011Suqs{
550222011Suqs    return __y;
551226283Sedwin}
552226283Sedwin
553226283Sedwin// general atomic<T>
554226283Sedwin
555226283Sedwintemplate <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
556226283Sedwinstruct __atomic_base  // false
557226283Sedwin{
558    mutable _Atomic(_Tp) __a_;
559
560    _LIBCPP_INLINE_VISIBILITY
561    bool is_lock_free() const volatile _NOEXCEPT
562        {return __c11_atomic_is_lock_free(sizeof(_Tp));}
563    _LIBCPP_INLINE_VISIBILITY
564    bool is_lock_free() const _NOEXCEPT
565        {return __c11_atomic_is_lock_free(sizeof(_Tp));}
566    _LIBCPP_INLINE_VISIBILITY
567    void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
568        {__c11_atomic_store(&__a_, __d, __m);}
569    _LIBCPP_INLINE_VISIBILITY
570    void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
571        {__c11_atomic_store(&__a_, __d, __m);}
572    _LIBCPP_INLINE_VISIBILITY
573    _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
574        {return __c11_atomic_load(&__a_, __m);}
575    _LIBCPP_INLINE_VISIBILITY
576    _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
577        {return __c11_atomic_load(&__a_, __m);}
578    _LIBCPP_INLINE_VISIBILITY
579    operator _Tp() const volatile _NOEXCEPT {return load();}
580    _LIBCPP_INLINE_VISIBILITY
581    operator _Tp() const _NOEXCEPT          {return load();}
582    _LIBCPP_INLINE_VISIBILITY
583    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
584        {return __c11_atomic_exchange(&__a_, __d, __m);}
585    _LIBCPP_INLINE_VISIBILITY
586    _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
587        {return __c11_atomic_exchange(&__a_, __d, __m);}
588    _LIBCPP_INLINE_VISIBILITY
589    bool compare_exchange_weak(_Tp& __e, _Tp __d,
590                               memory_order __s, memory_order __f) volatile _NOEXCEPT
591        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
592    _LIBCPP_INLINE_VISIBILITY
593    bool compare_exchange_weak(_Tp& __e, _Tp __d,
594                               memory_order __s, memory_order __f) _NOEXCEPT
595        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
596    _LIBCPP_INLINE_VISIBILITY
597    bool compare_exchange_strong(_Tp& __e, _Tp __d,
598                                 memory_order __s, memory_order __f) volatile _NOEXCEPT
599        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
600    _LIBCPP_INLINE_VISIBILITY
601    bool compare_exchange_strong(_Tp& __e, _Tp __d,
602                                 memory_order __s, memory_order __f) _NOEXCEPT
603        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
604    _LIBCPP_INLINE_VISIBILITY
605    bool compare_exchange_weak(_Tp& __e, _Tp __d,
606                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
607        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
608    _LIBCPP_INLINE_VISIBILITY
609    bool compare_exchange_weak(_Tp& __e, _Tp __d,
610                               memory_order __m = memory_order_seq_cst) _NOEXCEPT
611        {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
612    _LIBCPP_INLINE_VISIBILITY
613    bool compare_exchange_strong(_Tp& __e, _Tp __d,
614                              memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
615        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
616    _LIBCPP_INLINE_VISIBILITY
617    bool compare_exchange_strong(_Tp& __e, _Tp __d,
618                                 memory_order __m = memory_order_seq_cst) _NOEXCEPT
619        {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
620
621    _LIBCPP_INLINE_VISIBILITY
622    __atomic_base() _NOEXCEPT {} // = default;
623    _LIBCPP_INLINE_VISIBILITY
624    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
625#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
626    __atomic_base(const __atomic_base&) = delete;
627    __atomic_base& operator=(const __atomic_base&) = delete;
628    __atomic_base& operator=(const __atomic_base&) volatile = delete;
629#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
630private:
631    __atomic_base(const __atomic_base&);
632    __atomic_base& operator=(const __atomic_base&);
633    __atomic_base& operator=(const __atomic_base&) volatile;
634#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
635};
636
637// atomic<Integral>
638
639template <class _Tp>
640struct __atomic_base<_Tp, true>
641    : public __atomic_base<_Tp, false>
642{
643    typedef __atomic_base<_Tp, false> __base;
644    _LIBCPP_INLINE_VISIBILITY
645    __atomic_base() _NOEXCEPT {} // = default;
646    _LIBCPP_INLINE_VISIBILITY
647    _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
648
649    _LIBCPP_INLINE_VISIBILITY
650    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
651        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
652    _LIBCPP_INLINE_VISIBILITY
653    _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
654        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
655    _LIBCPP_INLINE_VISIBILITY
656    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
657        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
658    _LIBCPP_INLINE_VISIBILITY
659    _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
660        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
661    _LIBCPP_INLINE_VISIBILITY
662    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
663        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
664    _LIBCPP_INLINE_VISIBILITY
665    _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
666        {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
667    _LIBCPP_INLINE_VISIBILITY
668    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
669        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
670    _LIBCPP_INLINE_VISIBILITY
671    _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
672        {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
673    _LIBCPP_INLINE_VISIBILITY
674    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
675        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
676    _LIBCPP_INLINE_VISIBILITY
677    _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
678        {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
679
680    _LIBCPP_INLINE_VISIBILITY
681    _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
682    _LIBCPP_INLINE_VISIBILITY
683    _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
684    _LIBCPP_INLINE_VISIBILITY
685    _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
686    _LIBCPP_INLINE_VISIBILITY
687    _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
688    _LIBCPP_INLINE_VISIBILITY
689    _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
690    _LIBCPP_INLINE_VISIBILITY
691    _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
692    _LIBCPP_INLINE_VISIBILITY
693    _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
694    _LIBCPP_INLINE_VISIBILITY
695    _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
696    _LIBCPP_INLINE_VISIBILITY
697    _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
698    _LIBCPP_INLINE_VISIBILITY
699    _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
700    _LIBCPP_INLINE_VISIBILITY
701    _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
702    _LIBCPP_INLINE_VISIBILITY
703    _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
704    _LIBCPP_INLINE_VISIBILITY
705    _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
706    _LIBCPP_INLINE_VISIBILITY
707    _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
708    _LIBCPP_INLINE_VISIBILITY
709    _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
710    _LIBCPP_INLINE_VISIBILITY
711    _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
712    _LIBCPP_INLINE_VISIBILITY
713    _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
714    _LIBCPP_INLINE_VISIBILITY
715    _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
716};
717
718// atomic<T>
719
720template <class _Tp>
721struct atomic
722    : public __atomic_base<_Tp>
723{
724    typedef __atomic_base<_Tp> __base;
725    _LIBCPP_INLINE_VISIBILITY
726    atomic() _NOEXCEPT {} // = default;
727    _LIBCPP_INLINE_VISIBILITY
728    _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
729
730    _LIBCPP_INLINE_VISIBILITY
731    _Tp operator=(_Tp __d) volatile _NOEXCEPT
732        {__base::store(__d); return __d;}
733    _LIBCPP_INLINE_VISIBILITY
734    _Tp operator=(_Tp __d) _NOEXCEPT
735        {__base::store(__d); return __d;}
736};
737
738// atomic<T*>
739
740template <class _Tp>
741struct atomic<_Tp*>
742    : public __atomic_base<_Tp*>
743{
744    typedef __atomic_base<_Tp*> __base;
745    _LIBCPP_INLINE_VISIBILITY
746    atomic() _NOEXCEPT {} // = default;
747    _LIBCPP_INLINE_VISIBILITY
748    _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
749
750    _LIBCPP_INLINE_VISIBILITY
751    _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
752        {__base::store(__d); return __d;}
753    _LIBCPP_INLINE_VISIBILITY
754    _Tp* operator=(_Tp* __d) _NOEXCEPT
755        {__base::store(__d); return __d;}
756
757    _LIBCPP_INLINE_VISIBILITY
758    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
759                                                                        volatile _NOEXCEPT
760        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
761    _LIBCPP_INLINE_VISIBILITY
762    _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
763        {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
764    _LIBCPP_INLINE_VISIBILITY
765    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
766                                                                        volatile _NOEXCEPT
767        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
768    _LIBCPP_INLINE_VISIBILITY
769    _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
770        {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
771
772    _LIBCPP_INLINE_VISIBILITY
773    _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
774    _LIBCPP_INLINE_VISIBILITY
775    _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
776    _LIBCPP_INLINE_VISIBILITY
777    _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
778    _LIBCPP_INLINE_VISIBILITY
779    _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
780    _LIBCPP_INLINE_VISIBILITY
781    _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
782    _LIBCPP_INLINE_VISIBILITY
783    _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
784    _LIBCPP_INLINE_VISIBILITY
785    _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
786    _LIBCPP_INLINE_VISIBILITY
787    _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
788    _LIBCPP_INLINE_VISIBILITY
789    _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
790    _LIBCPP_INLINE_VISIBILITY
791    _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
792    _LIBCPP_INLINE_VISIBILITY
793    _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
794    _LIBCPP_INLINE_VISIBILITY
795    _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
796};
797
798// atomic_is_lock_free
799
800template <class _Tp>
801inline _LIBCPP_INLINE_VISIBILITY
802bool
803atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
804{
805    return __o->is_lock_free();
806}
807
808template <class _Tp>
809inline _LIBCPP_INLINE_VISIBILITY
810bool
811atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
812{
813    return __o->is_lock_free();
814}
815
816// atomic_init
817
818template <class _Tp>
819inline _LIBCPP_INLINE_VISIBILITY
820void
821atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
822{
823    __c11_atomic_init(&__o->__a_, __d);
824}
825
826template <class _Tp>
827inline _LIBCPP_INLINE_VISIBILITY
828void
829atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
830{
831    __c11_atomic_init(&__o->__a_, __d);
832}
833
834// atomic_store
835
836template <class _Tp>
837inline _LIBCPP_INLINE_VISIBILITY
838void
839atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
840{
841    __o->store(__d);
842}
843
844template <class _Tp>
845inline _LIBCPP_INLINE_VISIBILITY
846void
847atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
848{
849    __o->store(__d);
850}
851
852// atomic_store_explicit
853
854template <class _Tp>
855inline _LIBCPP_INLINE_VISIBILITY
856void
857atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
858{
859    __o->store(__d, __m);
860}
861
862template <class _Tp>
863inline _LIBCPP_INLINE_VISIBILITY
864void
865atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
866{
867    __o->store(__d, __m);
868}
869
870// atomic_load
871
872template <class _Tp>
873inline _LIBCPP_INLINE_VISIBILITY
874_Tp
875atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
876{
877    return __o->load();
878}
879
880template <class _Tp>
881inline _LIBCPP_INLINE_VISIBILITY
882_Tp
883atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
884{
885    return __o->load();
886}
887
888// atomic_load_explicit
889
890template <class _Tp>
891inline _LIBCPP_INLINE_VISIBILITY
892_Tp
893atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
894{
895    return __o->load(__m);
896}
897
898template <class _Tp>
899inline _LIBCPP_INLINE_VISIBILITY
900_Tp
901atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
902{
903    return __o->load(__m);
904}
905
906// atomic_exchange
907
908template <class _Tp>
909inline _LIBCPP_INLINE_VISIBILITY
910_Tp
911atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
912{
913    return __o->exchange(__d);
914}
915
916template <class _Tp>
917inline _LIBCPP_INLINE_VISIBILITY
918_Tp
919atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
920{
921    return __o->exchange(__d);
922}
923
924// atomic_exchange_explicit
925
926template <class _Tp>
927inline _LIBCPP_INLINE_VISIBILITY
928_Tp
929atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
930{
931    return __o->exchange(__d, __m);
932}
933
934template <class _Tp>
935inline _LIBCPP_INLINE_VISIBILITY
936_Tp
937atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
938{
939    return __o->exchange(__d, __m);
940}
941
942// atomic_compare_exchange_weak
943
944template <class _Tp>
945inline _LIBCPP_INLINE_VISIBILITY
946bool
947atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
948{
949    return __o->compare_exchange_weak(*__e, __d);
950}
951
952template <class _Tp>
953inline _LIBCPP_INLINE_VISIBILITY
954bool
955atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
956{
957    return __o->compare_exchange_weak(*__e, __d);
958}
959
960// atomic_compare_exchange_strong
961
962template <class _Tp>
963inline _LIBCPP_INLINE_VISIBILITY
964bool
965atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
966{
967    return __o->compare_exchange_strong(*__e, __d);
968}
969
970template <class _Tp>
971inline _LIBCPP_INLINE_VISIBILITY
972bool
973atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
974{
975    return __o->compare_exchange_strong(*__e, __d);
976}
977
978// atomic_compare_exchange_weak_explicit
979
980template <class _Tp>
981inline _LIBCPP_INLINE_VISIBILITY
982bool
983atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
984                                      _Tp __d,
985                                      memory_order __s, memory_order __f) _NOEXCEPT
986{
987    return __o->compare_exchange_weak(*__e, __d, __s, __f);
988}
989
990template <class _Tp>
991inline _LIBCPP_INLINE_VISIBILITY
992bool
993atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
994                                      memory_order __s, memory_order __f) _NOEXCEPT
995{
996    return __o->compare_exchange_weak(*__e, __d, __s, __f);
997}
998
999// atomic_compare_exchange_strong_explicit
1000
1001template <class _Tp>
1002inline _LIBCPP_INLINE_VISIBILITY
1003bool
1004atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1005                                        _Tp* __e, _Tp __d,
1006                                        memory_order __s, memory_order __f) _NOEXCEPT
1007{
1008    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1009}
1010
1011template <class _Tp>
1012inline _LIBCPP_INLINE_VISIBILITY
1013bool
1014atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1015                                        _Tp __d,
1016                                        memory_order __s, memory_order __f) _NOEXCEPT
1017{
1018    return __o->compare_exchange_strong(*__e, __d, __s, __f);
1019}
1020
1021// atomic_fetch_add
1022
1023template <class _Tp>
1024inline _LIBCPP_INLINE_VISIBILITY
1025typename enable_if
1026<
1027    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1028    _Tp
1029>::type
1030atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1031{
1032    return __o->fetch_add(__op);
1033}
1034
1035template <class _Tp>
1036inline _LIBCPP_INLINE_VISIBILITY
1037typename enable_if
1038<
1039    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1040    _Tp
1041>::type
1042atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1043{
1044    return __o->fetch_add(__op);
1045}
1046
1047template <class _Tp>
1048inline _LIBCPP_INLINE_VISIBILITY
1049_Tp*
1050atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1051{
1052    return __o->fetch_add(__op);
1053}
1054
1055template <class _Tp>
1056inline _LIBCPP_INLINE_VISIBILITY
1057_Tp*
1058atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1059{
1060    return __o->fetch_add(__op);
1061}
1062
1063// atomic_fetch_add_explicit
1064
1065template <class _Tp>
1066inline _LIBCPP_INLINE_VISIBILITY
1067typename enable_if
1068<
1069    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1070    _Tp
1071>::type
1072atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1073{
1074    return __o->fetch_add(__op, __m);
1075}
1076
1077template <class _Tp>
1078inline _LIBCPP_INLINE_VISIBILITY
1079typename enable_if
1080<
1081    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1082    _Tp
1083>::type
1084atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1085{
1086    return __o->fetch_add(__op, __m);
1087}
1088
1089template <class _Tp>
1090inline _LIBCPP_INLINE_VISIBILITY
1091_Tp*
1092atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1093                          memory_order __m) _NOEXCEPT
1094{
1095    return __o->fetch_add(__op, __m);
1096}
1097
1098template <class _Tp>
1099inline _LIBCPP_INLINE_VISIBILITY
1100_Tp*
1101atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
1102{
1103    return __o->fetch_add(__op, __m);
1104}
1105
1106// atomic_fetch_sub
1107
1108template <class _Tp>
1109inline _LIBCPP_INLINE_VISIBILITY
1110typename enable_if
1111<
1112    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1113    _Tp
1114>::type
1115atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1116{
1117    return __o->fetch_sub(__op);
1118}
1119
1120template <class _Tp>
1121inline _LIBCPP_INLINE_VISIBILITY
1122typename enable_if
1123<
1124    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1125    _Tp
1126>::type
1127atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1128{
1129    return __o->fetch_sub(__op);
1130}
1131
1132template <class _Tp>
1133inline _LIBCPP_INLINE_VISIBILITY
1134_Tp*
1135atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1136{
1137    return __o->fetch_sub(__op);
1138}
1139
1140template <class _Tp>
1141inline _LIBCPP_INLINE_VISIBILITY
1142_Tp*
1143atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
1144{
1145    return __o->fetch_sub(__op);
1146}
1147
1148// atomic_fetch_sub_explicit
1149
1150template <class _Tp>
1151inline _LIBCPP_INLINE_VISIBILITY
1152typename enable_if
1153<
1154    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1155    _Tp
1156>::type
1157atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1158{
1159    return __o->fetch_sub(__op, __m);
1160}
1161
1162template <class _Tp>
1163inline _LIBCPP_INLINE_VISIBILITY
1164typename enable_if
1165<
1166    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1167    _Tp
1168>::type
1169atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1170{
1171    return __o->fetch_sub(__op, __m);
1172}
1173
1174template <class _Tp>
1175inline _LIBCPP_INLINE_VISIBILITY
1176_Tp*
1177atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1178                          memory_order __m) _NOEXCEPT
1179{
1180    return __o->fetch_sub(__op, __m);
1181}
1182
1183template <class _Tp>
1184inline _LIBCPP_INLINE_VISIBILITY
1185_Tp*
1186atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
1187{
1188    return __o->fetch_sub(__op, __m);
1189}
1190
1191// atomic_fetch_and
1192
1193template <class _Tp>
1194inline _LIBCPP_INLINE_VISIBILITY
1195typename enable_if
1196<
1197    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1198    _Tp
1199>::type
1200atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1201{
1202    return __o->fetch_and(__op);
1203}
1204
1205template <class _Tp>
1206inline _LIBCPP_INLINE_VISIBILITY
1207typename enable_if
1208<
1209    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1210    _Tp
1211>::type
1212atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1213{
1214    return __o->fetch_and(__op);
1215}
1216
1217// atomic_fetch_and_explicit
1218
1219template <class _Tp>
1220inline _LIBCPP_INLINE_VISIBILITY
1221typename enable_if
1222<
1223    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1224    _Tp
1225>::type
1226atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1227{
1228    return __o->fetch_and(__op, __m);
1229}
1230
1231template <class _Tp>
1232inline _LIBCPP_INLINE_VISIBILITY
1233typename enable_if
1234<
1235    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1236    _Tp
1237>::type
1238atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1239{
1240    return __o->fetch_and(__op, __m);
1241}
1242
1243// atomic_fetch_or
1244
1245template <class _Tp>
1246inline _LIBCPP_INLINE_VISIBILITY
1247typename enable_if
1248<
1249    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1250    _Tp
1251>::type
1252atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1253{
1254    return __o->fetch_or(__op);
1255}
1256
1257template <class _Tp>
1258inline _LIBCPP_INLINE_VISIBILITY
1259typename enable_if
1260<
1261    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1262    _Tp
1263>::type
1264atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1265{
1266    return __o->fetch_or(__op);
1267}
1268
1269// atomic_fetch_or_explicit
1270
1271template <class _Tp>
1272inline _LIBCPP_INLINE_VISIBILITY
1273typename enable_if
1274<
1275    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1276    _Tp
1277>::type
1278atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1279{
1280    return __o->fetch_or(__op, __m);
1281}
1282
1283template <class _Tp>
1284inline _LIBCPP_INLINE_VISIBILITY
1285typename enable_if
1286<
1287    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1288    _Tp
1289>::type
1290atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1291{
1292    return __o->fetch_or(__op, __m);
1293}
1294
1295// atomic_fetch_xor
1296
1297template <class _Tp>
1298inline _LIBCPP_INLINE_VISIBILITY
1299typename enable_if
1300<
1301    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1302    _Tp
1303>::type
1304atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1305{
1306    return __o->fetch_xor(__op);
1307}
1308
1309template <class _Tp>
1310inline _LIBCPP_INLINE_VISIBILITY
1311typename enable_if
1312<
1313    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1314    _Tp
1315>::type
1316atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
1317{
1318    return __o->fetch_xor(__op);
1319}
1320
1321// atomic_fetch_xor_explicit
1322
1323template <class _Tp>
1324inline _LIBCPP_INLINE_VISIBILITY
1325typename enable_if
1326<
1327    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1328    _Tp
1329>::type
1330atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1331{
1332    return __o->fetch_xor(__op, __m);
1333}
1334
1335template <class _Tp>
1336inline _LIBCPP_INLINE_VISIBILITY
1337typename enable_if
1338<
1339    is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1340    _Tp
1341>::type
1342atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
1343{
1344    return __o->fetch_xor(__op, __m);
1345}
1346
1347// flag type and operations
1348
1349typedef struct atomic_flag
1350{
1351    _Atomic(bool) __a_;
1352
1353    _LIBCPP_INLINE_VISIBILITY
1354    bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1355        {return __c11_atomic_exchange(&__a_, true, __m);}
1356    _LIBCPP_INLINE_VISIBILITY
1357    bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1358        {return __c11_atomic_exchange(&__a_, true, __m);}
1359    _LIBCPP_INLINE_VISIBILITY
1360    void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
1361        {__c11_atomic_store(&__a_, false, __m);}
1362    _LIBCPP_INLINE_VISIBILITY
1363    void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
1364        {__c11_atomic_store(&__a_, false, __m);}
1365
1366    _LIBCPP_INLINE_VISIBILITY
1367    atomic_flag() _NOEXCEPT {} // = default;
1368    _LIBCPP_INLINE_VISIBILITY
1369    atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {}
1370
1371#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1372    atomic_flag(const atomic_flag&) = delete;
1373    atomic_flag& operator=(const atomic_flag&) = delete;
1374    atomic_flag& operator=(const atomic_flag&) volatile = delete;
1375#else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1376private:
1377    atomic_flag(const atomic_flag&);
1378    atomic_flag& operator=(const atomic_flag&);
1379    atomic_flag& operator=(const atomic_flag&) volatile;
1380#endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1381} atomic_flag;
1382
1383inline _LIBCPP_INLINE_VISIBILITY
1384bool
1385atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
1386{
1387    return __o->test_and_set();
1388}
1389
1390inline _LIBCPP_INLINE_VISIBILITY
1391bool
1392atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
1393{
1394    return __o->test_and_set();
1395}
1396
1397inline _LIBCPP_INLINE_VISIBILITY
1398bool
1399atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
1400{
1401    return __o->test_and_set(__m);
1402}
1403
1404inline _LIBCPP_INLINE_VISIBILITY
1405bool
1406atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
1407{
1408    return __o->test_and_set(__m);
1409}
1410
1411inline _LIBCPP_INLINE_VISIBILITY
1412void
1413atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
1414{
1415    __o->clear();
1416}
1417
1418inline _LIBCPP_INLINE_VISIBILITY
1419void
1420atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
1421{
1422    __o->clear();
1423}
1424
1425inline _LIBCPP_INLINE_VISIBILITY
1426void
1427atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
1428{
1429    __o->clear(__m);
1430}
1431
1432inline _LIBCPP_INLINE_VISIBILITY
1433void
1434atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
1435{
1436    __o->clear(__m);
1437}
1438
1439// fences
1440
1441inline _LIBCPP_INLINE_VISIBILITY
1442void
1443atomic_thread_fence(memory_order __m) _NOEXCEPT
1444{
1445    __c11_atomic_thread_fence(__m);
1446}
1447
1448inline _LIBCPP_INLINE_VISIBILITY
1449void
1450atomic_signal_fence(memory_order __m) _NOEXCEPT
1451{
1452    __c11_atomic_signal_fence(__m);
1453}
1454
1455// Atomics for standard typedef types
1456
1457typedef atomic<char>               atomic_char;
1458typedef atomic<signed char>        atomic_schar;
1459typedef atomic<unsigned char>      atomic_uchar;
1460typedef atomic<short>              atomic_short;
1461typedef atomic<unsigned short>     atomic_ushort;
1462typedef atomic<int>                atomic_int;
1463typedef atomic<unsigned int>       atomic_uint;
1464typedef atomic<long>               atomic_long;
1465typedef atomic<unsigned long>      atomic_ulong;
1466typedef atomic<long long>          atomic_llong;
1467typedef atomic<unsigned long long> atomic_ullong;
1468typedef atomic<char16_t>           atomic_char16_t;
1469typedef atomic<char32_t>           atomic_char32_t;
1470typedef atomic<wchar_t>            atomic_wchar_t;
1471
1472typedef atomic<int_least8_t>   atomic_int_least8_t;
1473typedef atomic<uint_least8_t>  atomic_uint_least8_t;
1474typedef atomic<int_least16_t>  atomic_int_least16_t;
1475typedef atomic<uint_least16_t> atomic_uint_least16_t;
1476typedef atomic<int_least32_t>  atomic_int_least32_t;
1477typedef atomic<uint_least32_t> atomic_uint_least32_t;
1478typedef atomic<int_least64_t>  atomic_int_least64_t;
1479typedef atomic<uint_least64_t> atomic_uint_least64_t;
1480
1481typedef atomic<int_fast8_t>   atomic_int_fast8_t;
1482typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
1483typedef atomic<int_fast16_t>  atomic_int_fast16_t;
1484typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1485typedef atomic<int_fast32_t>  atomic_int_fast32_t;
1486typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1487typedef atomic<int_fast64_t>  atomic_int_fast64_t;
1488typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1489
1490typedef atomic<intptr_t>  atomic_intptr_t;
1491typedef atomic<uintptr_t> atomic_uintptr_t;
1492typedef atomic<size_t>    atomic_size_t;
1493typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1494typedef atomic<intmax_t>  atomic_intmax_t;
1495typedef atomic<uintmax_t> atomic_uintmax_t;
1496
1497#define ATOMIC_FLAG_INIT {false}
1498#define ATOMIC_VAR_INIT(__v) {__v}
1499
1500// lock-free property
1501
1502#define ATOMIC_CHAR_LOCK_FREE 0
1503#define ATOMIC_CHAR16_T_LOCK_FREE 0
1504#define ATOMIC_CHAR32_T_LOCK_FREE 0
1505#define ATOMIC_WCHAR_T_LOCK_FREE 0
1506#define ATOMIC_SHORT_LOCK_FREE 0
1507#define ATOMIC_INT_LOCK_FREE 0
1508#define ATOMIC_LONG_LOCK_FREE 0
1509#define ATOMIC_LLONG_LOCK_FREE 0
1510
1511#endif  //  !__has_feature(cxx_atomic)
1512
1513_LIBCPP_END_NAMESPACE_STD
1514
1515#endif  // _LIBCPP_ATOMIC
1516