Home | History | Annotate | Download | only in include
      1 // -*- C++ -*-
      2 //===--------------------------- atomic -----------------------------------===//
      3 //
      4 //                     The LLVM Compiler Infrastructure
      5 //
      6 // This file is distributed under the University of Illinois Open Source
      7 // License. See LICENSE.TXT for details.
      8 //
      9 //===----------------------------------------------------------------------===//
     10 
     11 #ifndef _LIBCPP_ATOMIC
     12 #define _LIBCPP_ATOMIC
     13 
     14 /*
     15     atomic synopsis
     16 
     17 namespace std
     18 {
     19 
     20 // order and consistency
     21 
     22 typedef enum memory_order
     23 {
     24     memory_order_relaxed,
     25     memory_order_consume,  // load-consume
     26     memory_order_acquire,  // load-acquire
     27     memory_order_release,  // store-release
     28     memory_order_acq_rel,  // store-release load-acquire
     29     memory_order_seq_cst   // store-release load-acquire
     30 } memory_order;
     31 
     32 template <class T> T kill_dependency(T y) noexcept;
     33 
     34 // lock-free property
     35 
     36 #define ATOMIC_BOOL_LOCK_FREE unspecified
     37 #define ATOMIC_CHAR_LOCK_FREE unspecified
     38 #define ATOMIC_CHAR16_T_LOCK_FREE unspecified
     39 #define ATOMIC_CHAR32_T_LOCK_FREE unspecified
     40 #define ATOMIC_WCHAR_T_LOCK_FREE unspecified
     41 #define ATOMIC_SHORT_LOCK_FREE unspecified
     42 #define ATOMIC_INT_LOCK_FREE unspecified
     43 #define ATOMIC_LONG_LOCK_FREE unspecified
     44 #define ATOMIC_LLONG_LOCK_FREE unspecified
     45 #define ATOMIC_POINTER_LOCK_FREE unspecified
     46 
     47 // flag type and operations
     48 
     49 typedef struct atomic_flag
     50 {
     51     bool test_and_set(memory_order m = memory_order_seq_cst) volatile noexcept;
     52     bool test_and_set(memory_order m = memory_order_seq_cst) noexcept;
     53     void clear(memory_order m = memory_order_seq_cst) volatile noexcept;
     54     void clear(memory_order m = memory_order_seq_cst) noexcept;
     55     atomic_flag()  noexcept = default;
     56     atomic_flag(const atomic_flag&) = delete;
     57     atomic_flag& operator=(const atomic_flag&) = delete;
     58     atomic_flag& operator=(const atomic_flag&) volatile = delete;
     59 } atomic_flag;
     60 
     61 bool
     62     atomic_flag_test_and_set(volatile atomic_flag* obj) noexcept;
     63 
     64 bool
     65     atomic_flag_test_and_set(atomic_flag* obj) noexcept;
     66 
     67 bool
     68     atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
     69                                       memory_order m) noexcept;
     70 
     71 bool
     72     atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m) noexcept;
     73 
     74 void
     75     atomic_flag_clear(volatile atomic_flag* obj) noexcept;
     76 
     77 void
     78     atomic_flag_clear(atomic_flag* obj) noexcept;
     79 
     80 void
     81     atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m) noexcept;
     82 
     83 void
     84     atomic_flag_clear_explicit(atomic_flag* obj, memory_order m) noexcept;
     85 
     86 #define ATOMIC_FLAG_INIT see below
     87 #define ATOMIC_VAR_INIT(value) see below
     88 
     89 template <class T>
     90 struct atomic
     91 {
     92     bool is_lock_free() const volatile noexcept;
     93     bool is_lock_free() const noexcept;
     94     void store(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
     95     void store(T desr, memory_order m = memory_order_seq_cst) noexcept;
     96     T load(memory_order m = memory_order_seq_cst) const volatile noexcept;
     97     T load(memory_order m = memory_order_seq_cst) const noexcept;
     98     operator T() const volatile noexcept;
     99     operator T() const noexcept;
    100     T exchange(T desr, memory_order m = memory_order_seq_cst) volatile noexcept;
    101     T exchange(T desr, memory_order m = memory_order_seq_cst) noexcept;
    102     bool compare_exchange_weak(T& expc, T desr,
    103                                memory_order s, memory_order f) volatile noexcept;
    104     bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f) noexcept;
    105     bool compare_exchange_strong(T& expc, T desr,
    106                                  memory_order s, memory_order f) volatile noexcept;
    107     bool compare_exchange_strong(T& expc, T desr,
    108                                  memory_order s, memory_order f) noexcept;
    109     bool compare_exchange_weak(T& expc, T desr,
    110                                memory_order m = memory_order_seq_cst) volatile noexcept;
    111     bool compare_exchange_weak(T& expc, T desr,
    112                                memory_order m = memory_order_seq_cst) noexcept;
    113     bool compare_exchange_strong(T& expc, T desr,
    114                                 memory_order m = memory_order_seq_cst) volatile noexcept;
    115     bool compare_exchange_strong(T& expc, T desr,
    116                                  memory_order m = memory_order_seq_cst) noexcept;
    117 
    118     atomic() noexcept = default;
    119     constexpr atomic(T desr) noexcept;
    120     atomic(const atomic&) = delete;
    121     atomic& operator=(const atomic&) = delete;
    122     atomic& operator=(const atomic&) volatile = delete;
    123     T operator=(T) volatile noexcept;
    124     T operator=(T) noexcept;
    125 };
    126 
    127 template <>
    128 struct atomic<integral>
    129 {
    130     bool is_lock_free() const volatile noexcept;
    131     bool is_lock_free() const noexcept;
    132     void store(integral desr, memory_order m = memory_order_seq_cst) volatile noexcept;
    133     void store(integral desr, memory_order m = memory_order_seq_cst) noexcept;
    134     integral load(memory_order m = memory_order_seq_cst) const volatile noexcept;
    135     integral load(memory_order m = memory_order_seq_cst) const noexcept;
    136     operator integral() const volatile noexcept;
    137     operator integral() const noexcept;
    138     integral exchange(integral desr,
    139                       memory_order m = memory_order_seq_cst) volatile noexcept;
    140     integral exchange(integral desr, memory_order m = memory_order_seq_cst) noexcept;
    141     bool compare_exchange_weak(integral& expc, integral desr,
    142                                memory_order s, memory_order f) volatile noexcept;
    143     bool compare_exchange_weak(integral& expc, integral desr,
    144                                memory_order s, memory_order f) noexcept;
    145     bool compare_exchange_strong(integral& expc, integral desr,
    146                                  memory_order s, memory_order f) volatile noexcept;
    147     bool compare_exchange_strong(integral& expc, integral desr,
    148                                  memory_order s, memory_order f) noexcept;
    149     bool compare_exchange_weak(integral& expc, integral desr,
    150                                memory_order m = memory_order_seq_cst) volatile noexcept;
    151     bool compare_exchange_weak(integral& expc, integral desr,
    152                                memory_order m = memory_order_seq_cst) noexcept;
    153     bool compare_exchange_strong(integral& expc, integral desr,
    154                                 memory_order m = memory_order_seq_cst) volatile noexcept;
    155     bool compare_exchange_strong(integral& expc, integral desr,
    156                                  memory_order m = memory_order_seq_cst) noexcept;
    157 
    158     integral
    159         fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
    160     integral fetch_add(integral op, memory_order m = memory_order_seq_cst) noexcept;
    161     integral
    162         fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
    163     integral fetch_sub(integral op, memory_order m = memory_order_seq_cst) noexcept;
    164     integral
    165         fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
    166     integral fetch_and(integral op, memory_order m = memory_order_seq_cst) noexcept;
    167     integral
    168         fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
    169     integral fetch_or(integral op, memory_order m = memory_order_seq_cst) noexcept;
    170     integral
    171         fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile noexcept;
    172     integral fetch_xor(integral op, memory_order m = memory_order_seq_cst) noexcept;
    173 
    174     atomic() noexcept = default;
    175     constexpr atomic(integral desr) noexcept;
    176     atomic(const atomic&) = delete;
    177     atomic& operator=(const atomic&) = delete;
    178     atomic& operator=(const atomic&) volatile = delete;
    179     integral operator=(integral desr) volatile noexcept;
    180     integral operator=(integral desr) noexcept;
    181 
    182     integral operator++(int) volatile noexcept;
    183     integral operator++(int) noexcept;
    184     integral operator--(int) volatile noexcept;
    185     integral operator--(int) noexcept;
    186     integral operator++() volatile noexcept;
    187     integral operator++() noexcept;
    188     integral operator--() volatile noexcept;
    189     integral operator--() noexcept;
    190     integral operator+=(integral op) volatile noexcept;
    191     integral operator+=(integral op) noexcept;
    192     integral operator-=(integral op) volatile noexcept;
    193     integral operator-=(integral op) noexcept;
    194     integral operator&=(integral op) volatile noexcept;
    195     integral operator&=(integral op) noexcept;
    196     integral operator|=(integral op) volatile noexcept;
    197     integral operator|=(integral op) noexcept;
    198     integral operator^=(integral op) volatile noexcept;
    199     integral operator^=(integral op) noexcept;
    200 };
    201 
    202 template <class T>
    203 struct atomic<T*>
    204 {
    205     bool is_lock_free() const volatile noexcept;
    206     bool is_lock_free() const noexcept;
    207     void store(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
    208     void store(T* desr, memory_order m = memory_order_seq_cst) noexcept;
    209     T* load(memory_order m = memory_order_seq_cst) const volatile noexcept;
    210     T* load(memory_order m = memory_order_seq_cst) const noexcept;
    211     operator T*() const volatile noexcept;
    212     operator T*() const noexcept;
    213     T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile noexcept;
    214     T* exchange(T* desr, memory_order m = memory_order_seq_cst) noexcept;
    215     bool compare_exchange_weak(T*& expc, T* desr,
    216                                memory_order s, memory_order f) volatile noexcept;
    217     bool compare_exchange_weak(T*& expc, T* desr,
    218                                memory_order s, memory_order f) noexcept;
    219     bool compare_exchange_strong(T*& expc, T* desr,
    220                                  memory_order s, memory_order f) volatile noexcept;
    221     bool compare_exchange_strong(T*& expc, T* desr,
    222                                  memory_order s, memory_order f) noexcept;
    223     bool compare_exchange_weak(T*& expc, T* desr,
    224                                memory_order m = memory_order_seq_cst) volatile noexcept;
    225     bool compare_exchange_weak(T*& expc, T* desr,
    226                                memory_order m = memory_order_seq_cst) noexcept;
    227     bool compare_exchange_strong(T*& expc, T* desr,
    228                                 memory_order m = memory_order_seq_cst) volatile noexcept;
    229     bool compare_exchange_strong(T*& expc, T* desr,
    230                                  memory_order m = memory_order_seq_cst) noexcept;
    231     T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
    232     T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
    233     T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile noexcept;
    234     T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) noexcept;
    235 
    236     atomic() noexcept = default;
    237     constexpr atomic(T* desr) noexcept;
    238     atomic(const atomic&) = delete;
    239     atomic& operator=(const atomic&) = delete;
    240     atomic& operator=(const atomic&) volatile = delete;
    241 
    242     T* operator=(T*) volatile noexcept;
    243     T* operator=(T*) noexcept;
    244     T* operator++(int) volatile noexcept;
    245     T* operator++(int) noexcept;
    246     T* operator--(int) volatile noexcept;
    247     T* operator--(int) noexcept;
    248     T* operator++() volatile noexcept;
    249     T* operator++() noexcept;
    250     T* operator--() volatile noexcept;
    251     T* operator--() noexcept;
    252     T* operator+=(ptrdiff_t op) volatile noexcept;
    253     T* operator+=(ptrdiff_t op) noexcept;
    254     T* operator-=(ptrdiff_t op) volatile noexcept;
    255     T* operator-=(ptrdiff_t op) noexcept;
    256 };
    257 
    258 
    259 template <class T>
    260     bool
    261     atomic_is_lock_free(const volatile atomic<T>* obj) noexcept;
    262 
    263 template <class T>
    264     bool
    265     atomic_is_lock_free(const atomic<T>* obj) noexcept;
    266 
    267 template <class T>
    268     void
    269     atomic_init(volatile atomic<T>* obj, T desr) noexcept;
    270 
    271 template <class T>
    272     void
    273     atomic_init(atomic<T>* obj, T desr) noexcept;
    274 
    275 template <class T>
    276     void
    277     atomic_store(volatile atomic<T>* obj, T desr) noexcept;
    278 
    279 template <class T>
    280     void
    281     atomic_store(atomic<T>* obj, T desr) noexcept;
    282 
    283 template <class T>
    284     void
    285     atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
    286 
    287 template <class T>
    288     void
    289     atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
    290 
    291 template <class T>
    292     T
    293     atomic_load(const volatile atomic<T>* obj) noexcept;
    294 
    295 template <class T>
    296     T
    297     atomic_load(const atomic<T>* obj) noexcept;
    298 
    299 template <class T>
    300     T
    301     atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept;
    302 
    303 template <class T>
    304     T
    305     atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept;
    306 
    307 template <class T>
    308     T
    309     atomic_exchange(volatile atomic<T>* obj, T desr) noexcept;
    310 
    311 template <class T>
    312     T
    313     atomic_exchange(atomic<T>* obj, T desr) noexcept;
    314 
    315 template <class T>
    316     T
    317     atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept;
    318 
    319 template <class T>
    320     T
    321     atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept;
    322 
    323 template <class T>
    324     bool
    325     atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept;
    326 
    327 template <class T>
    328     bool
    329     atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept;
    330 
    331 template <class T>
    332     bool
    333     atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept;
    334 
    335 template <class T>
    336     bool
    337     atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept;
    338 
    339 template <class T>
    340     bool
    341     atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
    342                                           T desr,
    343                                           memory_order s, memory_order f) noexcept;
    344 
    345 template <class T>
    346     bool
    347     atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
    348                                           memory_order s, memory_order f) noexcept;
    349 
    350 template <class T>
    351     bool
    352     atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
    353                                             T* expc, T desr,
    354                                             memory_order s, memory_order f) noexcept;
    355 
    356 template <class T>
    357     bool
    358     atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
    359                                             T desr,
    360                                             memory_order s, memory_order f) noexcept;
    361 
    362 template <class Integral>
    363     Integral
    364     atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept;
    365 
    366 template <class Integral>
    367     Integral
    368     atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept;
    369 
    370 template <class Integral>
    371     Integral
    372     atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
    373                               memory_order m) noexcept;
    374 template <class Integral>
    375     Integral
    376     atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
    377                               memory_order m) noexcept;
    378 template <class Integral>
    379     Integral
    380     atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept;
    381 
    382 template <class Integral>
    383     Integral
    384     atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept;
    385 
    386 template <class Integral>
    387     Integral
    388     atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
    389                               memory_order m) noexcept;
    390 template <class Integral>
    391     Integral
    392     atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
    393                               memory_order m) noexcept;
    394 template <class Integral>
    395     Integral
    396     atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept;
    397 
    398 template <class Integral>
    399     Integral
    400     atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept;
    401 
    402 template <class Integral>
    403     Integral
    404     atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
    405                               memory_order m) noexcept;
    406 template <class Integral>
    407     Integral
    408     atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
    409                               memory_order m) noexcept;
    410 template <class Integral>
    411     Integral
    412     atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept;
    413 
    414 template <class Integral>
    415     Integral
    416     atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept;
    417 
    418 template <class Integral>
    419     Integral
    420     atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
    421                              memory_order m) noexcept;
    422 template <class Integral>
    423     Integral
    424     atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
    425                              memory_order m) noexcept;
    426 template <class Integral>
    427     Integral
    428     atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept;
    429 
    430 template <class Integral>
    431     Integral
    432     atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept;
    433 
    434 template <class Integral>
    435     Integral
    436     atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
    437                               memory_order m) noexcept;
    438 template <class Integral>
    439     Integral
    440     atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
    441                               memory_order m) noexcept;
    442 
    443 template <class T>
    444     T*
    445     atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
    446 
    447 template <class T>
    448     T*
    449     atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept;
    450 
    451 template <class T>
    452     T*
    453     atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
    454                               memory_order m) noexcept;
    455 template <class T>
    456     T*
    457     atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
    458 
    459 template <class T>
    460     T*
    461     atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept;
    462 
    463 template <class T>
    464     T*
    465     atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept;
    466 
    467 template <class T>
    468     T*
    469     atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
    470                               memory_order m) noexcept;
    471 template <class T>
    472     T*
    473     atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept;
    474 
    475 // Atomics for standard typedef types
    476 
    477 typedef atomic<bool>               atomic_bool;
    478 typedef atomic<char>               atomic_char;
    479 typedef atomic<signed char>        atomic_schar;
    480 typedef atomic<unsigned char>      atomic_uchar;
    481 typedef atomic<short>              atomic_short;
    482 typedef atomic<unsigned short>     atomic_ushort;
    483 typedef atomic<int>                atomic_int;
    484 typedef atomic<unsigned int>       atomic_uint;
    485 typedef atomic<long>               atomic_long;
    486 typedef atomic<unsigned long>      atomic_ulong;
    487 typedef atomic<long long>          atomic_llong;
    488 typedef atomic<unsigned long long> atomic_ullong;
    489 typedef atomic<char16_t>           atomic_char16_t;
    490 typedef atomic<char32_t>           atomic_char32_t;
    491 typedef atomic<wchar_t>            atomic_wchar_t;
    492 
    493 typedef atomic<int_least8_t>   atomic_int_least8_t;
    494 typedef atomic<uint_least8_t>  atomic_uint_least8_t;
    495 typedef atomic<int_least16_t>  atomic_int_least16_t;
    496 typedef atomic<uint_least16_t> atomic_uint_least16_t;
    497 typedef atomic<int_least32_t>  atomic_int_least32_t;
    498 typedef atomic<uint_least32_t> atomic_uint_least32_t;
    499 typedef atomic<int_least64_t>  atomic_int_least64_t;
    500 typedef atomic<uint_least64_t> atomic_uint_least64_t;
    501 
    502 typedef atomic<int_fast8_t>   atomic_int_fast8_t;
    503 typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
    504 typedef atomic<int_fast16_t>  atomic_int_fast16_t;
    505 typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
    506 typedef atomic<int_fast32_t>  atomic_int_fast32_t;
    507 typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
    508 typedef atomic<int_fast64_t>  atomic_int_fast64_t;
    509 typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
    510 
    511 typedef atomic<intptr_t>  atomic_intptr_t;
    512 typedef atomic<uintptr_t> atomic_uintptr_t;
    513 typedef atomic<size_t>    atomic_size_t;
    514 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
    515 typedef atomic<intmax_t>  atomic_intmax_t;
    516 typedef atomic<uintmax_t> atomic_uintmax_t;
    517 
    518 // fences
    519 
    520 void atomic_thread_fence(memory_order m) noexcept;
    521 void atomic_signal_fence(memory_order m) noexcept;
    522 
    523 }  // std
    524 
    525 */
    526 
    527 #include <__config>
    528 #include <cstddef>
    529 #include <cstdint>
    530 #include <type_traits>
    531 
    532 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
    533 #pragma GCC system_header
    534 #endif
    535 
    536 _LIBCPP_BEGIN_NAMESPACE_STD
    537 
    538 #if !__has_feature(cxx_atomic)
    539 #error <atomic> is not implemented
    540 #else
    541 
    542 typedef enum memory_order
    543 {
    544     memory_order_relaxed, memory_order_consume, memory_order_acquire,
    545     memory_order_release, memory_order_acq_rel, memory_order_seq_cst
    546 } memory_order;
    547 
    548 template <class _Tp>
    549 inline _LIBCPP_INLINE_VISIBILITY
    550 _Tp
    551 kill_dependency(_Tp __y) _NOEXCEPT
    552 {
    553     return __y;
    554 }
    555 
    556 // general atomic<T>
    557 
    558 template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
    559 struct __atomic_base  // false
    560 {
    561     mutable _Atomic(_Tp) __a_;
    562 
    563     _LIBCPP_INLINE_VISIBILITY
    564     bool is_lock_free() const volatile _NOEXCEPT
    565         {return __c11_atomic_is_lock_free(sizeof(_Tp));}
    566     _LIBCPP_INLINE_VISIBILITY
    567     bool is_lock_free() const _NOEXCEPT
    568         {return __c11_atomic_is_lock_free(sizeof(_Tp));}
    569     _LIBCPP_INLINE_VISIBILITY
    570     void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
    571         {__c11_atomic_store(&__a_, __d, __m);}
    572     _LIBCPP_INLINE_VISIBILITY
    573     void store(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
    574         {__c11_atomic_store(&__a_, __d, __m);}
    575     _LIBCPP_INLINE_VISIBILITY
    576     _Tp load(memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
    577         {return __c11_atomic_load(&__a_, __m);}
    578     _LIBCPP_INLINE_VISIBILITY
    579     _Tp load(memory_order __m = memory_order_seq_cst) const _NOEXCEPT
    580         {return __c11_atomic_load(&__a_, __m);}
    581     _LIBCPP_INLINE_VISIBILITY
    582     operator _Tp() const volatile _NOEXCEPT {return load();}
    583     _LIBCPP_INLINE_VISIBILITY
    584     operator _Tp() const _NOEXCEPT          {return load();}
    585     _LIBCPP_INLINE_VISIBILITY
    586     _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
    587         {return __c11_atomic_exchange(&__a_, __d, __m);}
    588     _LIBCPP_INLINE_VISIBILITY
    589     _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
    590         {return __c11_atomic_exchange(&__a_, __d, __m);}
    591     _LIBCPP_INLINE_VISIBILITY
    592     bool compare_exchange_weak(_Tp& __e, _Tp __d,
    593                                memory_order __s, memory_order __f) volatile _NOEXCEPT
    594         {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
    595     _LIBCPP_INLINE_VISIBILITY
    596     bool compare_exchange_weak(_Tp& __e, _Tp __d,
    597                                memory_order __s, memory_order __f) _NOEXCEPT
    598         {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
    599     _LIBCPP_INLINE_VISIBILITY
    600     bool compare_exchange_strong(_Tp& __e, _Tp __d,
    601                                  memory_order __s, memory_order __f) volatile _NOEXCEPT
    602         {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
    603     _LIBCPP_INLINE_VISIBILITY
    604     bool compare_exchange_strong(_Tp& __e, _Tp __d,
    605                                  memory_order __s, memory_order __f) _NOEXCEPT
    606         {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
    607     _LIBCPP_INLINE_VISIBILITY
    608     bool compare_exchange_weak(_Tp& __e, _Tp __d,
    609                               memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
    610         {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
    611     _LIBCPP_INLINE_VISIBILITY
    612     bool compare_exchange_weak(_Tp& __e, _Tp __d,
    613                                memory_order __m = memory_order_seq_cst) _NOEXCEPT
    614         {return __c11_atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
    615     _LIBCPP_INLINE_VISIBILITY
    616     bool compare_exchange_strong(_Tp& __e, _Tp __d,
    617                               memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
    618         {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
    619     _LIBCPP_INLINE_VISIBILITY
    620     bool compare_exchange_strong(_Tp& __e, _Tp __d,
    621                                  memory_order __m = memory_order_seq_cst) _NOEXCEPT
    622         {return __c11_atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
    623 
    624     _LIBCPP_INLINE_VISIBILITY
    625 #ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
    626     __atomic_base() _NOEXCEPT = default;
    627 #else
    628     __atomic_base() _NOEXCEPT : __a_() {}
    629 #endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
    630 
    631     _LIBCPP_INLINE_VISIBILITY
    632     _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __a_(__d) {}
    633 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
    634     __atomic_base(const __atomic_base&) = delete;
    635     __atomic_base& operator=(const __atomic_base&) = delete;
    636     __atomic_base& operator=(const __atomic_base&) volatile = delete;
    637 #else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
    638 private:
    639     __atomic_base(const __atomic_base&);
    640     __atomic_base& operator=(const __atomic_base&);
    641     __atomic_base& operator=(const __atomic_base&) volatile;
    642 #endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
    643 };
    644 
    645 // atomic<Integral>
    646 
    647 template <class _Tp>
    648 struct __atomic_base<_Tp, true>
    649     : public __atomic_base<_Tp, false>
    650 {
    651     typedef __atomic_base<_Tp, false> __base;
    652     _LIBCPP_INLINE_VISIBILITY
    653     __atomic_base() _NOEXCEPT _LIBCPP_DEFAULT
    654     _LIBCPP_INLINE_VISIBILITY
    655     _LIBCPP_CONSTEXPR __atomic_base(_Tp __d) _NOEXCEPT : __base(__d) {}
    656 
    657     _LIBCPP_INLINE_VISIBILITY
    658     _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
    659         {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
    660     _LIBCPP_INLINE_VISIBILITY
    661     _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
    662         {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
    663     _LIBCPP_INLINE_VISIBILITY
    664     _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
    665         {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
    666     _LIBCPP_INLINE_VISIBILITY
    667     _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
    668         {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
    669     _LIBCPP_INLINE_VISIBILITY
    670     _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
    671         {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
    672     _LIBCPP_INLINE_VISIBILITY
    673     _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
    674         {return __c11_atomic_fetch_and(&this->__a_, __op, __m);}
    675     _LIBCPP_INLINE_VISIBILITY
    676     _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
    677         {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
    678     _LIBCPP_INLINE_VISIBILITY
    679     _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
    680         {return __c11_atomic_fetch_or(&this->__a_, __op, __m);}
    681     _LIBCPP_INLINE_VISIBILITY
    682     _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
    683         {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
    684     _LIBCPP_INLINE_VISIBILITY
    685     _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
    686         {return __c11_atomic_fetch_xor(&this->__a_, __op, __m);}
    687 
    688     _LIBCPP_INLINE_VISIBILITY
    689     _Tp operator++(int) volatile _NOEXCEPT      {return fetch_add(_Tp(1));}
    690     _LIBCPP_INLINE_VISIBILITY
    691     _Tp operator++(int) _NOEXCEPT               {return fetch_add(_Tp(1));}
    692     _LIBCPP_INLINE_VISIBILITY
    693     _Tp operator--(int) volatile _NOEXCEPT      {return fetch_sub(_Tp(1));}
    694     _LIBCPP_INLINE_VISIBILITY
    695     _Tp operator--(int) _NOEXCEPT               {return fetch_sub(_Tp(1));}
    696     _LIBCPP_INLINE_VISIBILITY
    697     _Tp operator++() volatile _NOEXCEPT         {return fetch_add(_Tp(1)) + _Tp(1);}
    698     _LIBCPP_INLINE_VISIBILITY
    699     _Tp operator++() _NOEXCEPT                  {return fetch_add(_Tp(1)) + _Tp(1);}
    700     _LIBCPP_INLINE_VISIBILITY
    701     _Tp operator--() volatile _NOEXCEPT         {return fetch_sub(_Tp(1)) - _Tp(1);}
    702     _LIBCPP_INLINE_VISIBILITY
    703     _Tp operator--() _NOEXCEPT                  {return fetch_sub(_Tp(1)) - _Tp(1);}
    704     _LIBCPP_INLINE_VISIBILITY
    705     _Tp operator+=(_Tp __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
    706     _LIBCPP_INLINE_VISIBILITY
    707     _Tp operator+=(_Tp __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
    708     _LIBCPP_INLINE_VISIBILITY
    709     _Tp operator-=(_Tp __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
    710     _LIBCPP_INLINE_VISIBILITY
    711     _Tp operator-=(_Tp __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
    712     _LIBCPP_INLINE_VISIBILITY
    713     _Tp operator&=(_Tp __op) volatile _NOEXCEPT {return fetch_and(__op) & __op;}
    714     _LIBCPP_INLINE_VISIBILITY
    715     _Tp operator&=(_Tp __op) _NOEXCEPT          {return fetch_and(__op) & __op;}
    716     _LIBCPP_INLINE_VISIBILITY
    717     _Tp operator|=(_Tp __op) volatile _NOEXCEPT {return fetch_or(__op) | __op;}
    718     _LIBCPP_INLINE_VISIBILITY
    719     _Tp operator|=(_Tp __op) _NOEXCEPT          {return fetch_or(__op) | __op;}
    720     _LIBCPP_INLINE_VISIBILITY
    721     _Tp operator^=(_Tp __op) volatile _NOEXCEPT {return fetch_xor(__op) ^ __op;}
    722     _LIBCPP_INLINE_VISIBILITY
    723     _Tp operator^=(_Tp __op) _NOEXCEPT          {return fetch_xor(__op) ^ __op;}
    724 };
    725 
    726 // atomic<T>
    727 
    728 template <class _Tp>
    729 struct atomic
    730     : public __atomic_base<_Tp>
    731 {
    732     typedef __atomic_base<_Tp> __base;
    733     _LIBCPP_INLINE_VISIBILITY
    734     atomic() _NOEXCEPT _LIBCPP_DEFAULT
    735     _LIBCPP_INLINE_VISIBILITY
    736     _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
    737 
    738     _LIBCPP_INLINE_VISIBILITY
    739     _Tp operator=(_Tp __d) volatile _NOEXCEPT
    740         {__base::store(__d); return __d;}
    741     _LIBCPP_INLINE_VISIBILITY
    742     _Tp operator=(_Tp __d) _NOEXCEPT
    743         {__base::store(__d); return __d;}
    744 };
    745 
    746 // atomic<T*>
    747 
    748 template <class _Tp>
    749 struct atomic<_Tp*>
    750     : public __atomic_base<_Tp*>
    751 {
    752     typedef __atomic_base<_Tp*> __base;
    753     _LIBCPP_INLINE_VISIBILITY
    754     atomic() _NOEXCEPT _LIBCPP_DEFAULT
    755     _LIBCPP_INLINE_VISIBILITY
    756     _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
    757 
    758     _LIBCPP_INLINE_VISIBILITY
    759     _Tp* operator=(_Tp* __d) volatile _NOEXCEPT
    760         {__base::store(__d); return __d;}
    761     _LIBCPP_INLINE_VISIBILITY
    762     _Tp* operator=(_Tp* __d) _NOEXCEPT
    763         {__base::store(__d); return __d;}
    764 
    765     _LIBCPP_INLINE_VISIBILITY
    766     _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
    767                                                                         volatile _NOEXCEPT
    768         {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
    769     _LIBCPP_INLINE_VISIBILITY
    770     _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
    771         {return __c11_atomic_fetch_add(&this->__a_, __op, __m);}
    772     _LIBCPP_INLINE_VISIBILITY
    773     _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
    774                                                                         volatile _NOEXCEPT
    775         {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
    776     _LIBCPP_INLINE_VISIBILITY
    777     _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT
    778         {return __c11_atomic_fetch_sub(&this->__a_, __op, __m);}
    779 
    780     _LIBCPP_INLINE_VISIBILITY
    781     _Tp* operator++(int) volatile _NOEXCEPT            {return fetch_add(1);}
    782     _LIBCPP_INLINE_VISIBILITY
    783     _Tp* operator++(int) _NOEXCEPT                     {return fetch_add(1);}
    784     _LIBCPP_INLINE_VISIBILITY
    785     _Tp* operator--(int) volatile _NOEXCEPT            {return fetch_sub(1);}
    786     _LIBCPP_INLINE_VISIBILITY
    787     _Tp* operator--(int) _NOEXCEPT                     {return fetch_sub(1);}
    788     _LIBCPP_INLINE_VISIBILITY
    789     _Tp* operator++() volatile _NOEXCEPT               {return fetch_add(1) + 1;}
    790     _LIBCPP_INLINE_VISIBILITY
    791     _Tp* operator++() _NOEXCEPT                        {return fetch_add(1) + 1;}
    792     _LIBCPP_INLINE_VISIBILITY
    793     _Tp* operator--() volatile _NOEXCEPT               {return fetch_sub(1) - 1;}
    794     _LIBCPP_INLINE_VISIBILITY
    795     _Tp* operator--() _NOEXCEPT                        {return fetch_sub(1) - 1;}
    796     _LIBCPP_INLINE_VISIBILITY
    797     _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_add(__op) + __op;}
    798     _LIBCPP_INLINE_VISIBILITY
    799     _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT          {return fetch_add(__op) + __op;}
    800     _LIBCPP_INLINE_VISIBILITY
    801     _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT {return fetch_sub(__op) - __op;}
    802     _LIBCPP_INLINE_VISIBILITY
    803     _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT          {return fetch_sub(__op) - __op;}
    804 };
    805 
    806 // atomic_is_lock_free
    807 
    808 template <class _Tp>
    809 inline _LIBCPP_INLINE_VISIBILITY
    810 bool
    811 atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT
    812 {
    813     return __o->is_lock_free();
    814 }
    815 
    816 template <class _Tp>
    817 inline _LIBCPP_INLINE_VISIBILITY
    818 bool
    819 atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
    820 {
    821     return __o->is_lock_free();
    822 }
    823 
    824 // atomic_init
    825 
    826 template <class _Tp>
    827 inline _LIBCPP_INLINE_VISIBILITY
    828 void
    829 atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
    830 {
    831     __c11_atomic_init(&__o->__a_, __d);
    832 }
    833 
    834 template <class _Tp>
    835 inline _LIBCPP_INLINE_VISIBILITY
    836 void
    837 atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
    838 {
    839     __c11_atomic_init(&__o->__a_, __d);
    840 }
    841 
    842 // atomic_store
    843 
    844 template <class _Tp>
    845 inline _LIBCPP_INLINE_VISIBILITY
    846 void
    847 atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
    848 {
    849     __o->store(__d);
    850 }
    851 
    852 template <class _Tp>
    853 inline _LIBCPP_INLINE_VISIBILITY
    854 void
    855 atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
    856 {
    857     __o->store(__d);
    858 }
    859 
    860 // atomic_store_explicit
    861 
    862 template <class _Tp>
    863 inline _LIBCPP_INLINE_VISIBILITY
    864 void
    865 atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
    866 {
    867     __o->store(__d, __m);
    868 }
    869 
    870 template <class _Tp>
    871 inline _LIBCPP_INLINE_VISIBILITY
    872 void
    873 atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
    874 {
    875     __o->store(__d, __m);
    876 }
    877 
    878 // atomic_load
    879 
    880 template <class _Tp>
    881 inline _LIBCPP_INLINE_VISIBILITY
    882 _Tp
    883 atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT
    884 {
    885     return __o->load();
    886 }
    887 
    888 template <class _Tp>
    889 inline _LIBCPP_INLINE_VISIBILITY
    890 _Tp
    891 atomic_load(const atomic<_Tp>* __o) _NOEXCEPT
    892 {
    893     return __o->load();
    894 }
    895 
    896 // atomic_load_explicit
    897 
    898 template <class _Tp>
    899 inline _LIBCPP_INLINE_VISIBILITY
    900 _Tp
    901 atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
    902 {
    903     return __o->load(__m);
    904 }
    905 
    906 template <class _Tp>
    907 inline _LIBCPP_INLINE_VISIBILITY
    908 _Tp
    909 atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
    910 {
    911     return __o->load(__m);
    912 }
    913 
    914 // atomic_exchange
    915 
    916 template <class _Tp>
    917 inline _LIBCPP_INLINE_VISIBILITY
    918 _Tp
    919 atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
    920 {
    921     return __o->exchange(__d);
    922 }
    923 
    924 template <class _Tp>
    925 inline _LIBCPP_INLINE_VISIBILITY
    926 _Tp
    927 atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
    928 {
    929     return __o->exchange(__d);
    930 }
    931 
    932 // atomic_exchange_explicit
    933 
    934 template <class _Tp>
    935 inline _LIBCPP_INLINE_VISIBILITY
    936 _Tp
    937 atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
    938 {
    939     return __o->exchange(__d, __m);
    940 }
    941 
    942 template <class _Tp>
    943 inline _LIBCPP_INLINE_VISIBILITY
    944 _Tp
    945 atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
    946 {
    947     return __o->exchange(__d, __m);
    948 }
    949 
    950 // atomic_compare_exchange_weak
    951 
    952 template <class _Tp>
    953 inline _LIBCPP_INLINE_VISIBILITY
    954 bool
    955 atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
    956 {
    957     return __o->compare_exchange_weak(*__e, __d);
    958 }
    959 
    960 template <class _Tp>
    961 inline _LIBCPP_INLINE_VISIBILITY
    962 bool
    963 atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
    964 {
    965     return __o->compare_exchange_weak(*__e, __d);
    966 }
    967 
    968 // atomic_compare_exchange_strong
    969 
    970 template <class _Tp>
    971 inline _LIBCPP_INLINE_VISIBILITY
    972 bool
    973 atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
    974 {
    975     return __o->compare_exchange_strong(*__e, __d);
    976 }
    977 
    978 template <class _Tp>
    979 inline _LIBCPP_INLINE_VISIBILITY
    980 bool
    981 atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
    982 {
    983     return __o->compare_exchange_strong(*__e, __d);
    984 }
    985 
    986 // atomic_compare_exchange_weak_explicit
    987 
    988 template <class _Tp>
    989 inline _LIBCPP_INLINE_VISIBILITY
    990 bool
    991 atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
    992                                       _Tp __d,
    993                                       memory_order __s, memory_order __f) _NOEXCEPT
    994 {
    995     return __o->compare_exchange_weak(*__e, __d, __s, __f);
    996 }
    997 
    998 template <class _Tp>
    999 inline _LIBCPP_INLINE_VISIBILITY
   1000 bool
   1001 atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
   1002                                       memory_order __s, memory_order __f) _NOEXCEPT
   1003 {
   1004     return __o->compare_exchange_weak(*__e, __d, __s, __f);
   1005 }
   1006 
   1007 // atomic_compare_exchange_strong_explicit
   1008 
   1009 template <class _Tp>
   1010 inline _LIBCPP_INLINE_VISIBILITY
   1011 bool
   1012 atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
   1013                                         _Tp* __e, _Tp __d,
   1014                                         memory_order __s, memory_order __f) _NOEXCEPT
   1015 {
   1016     return __o->compare_exchange_strong(*__e, __d, __s, __f);
   1017 }
   1018 
   1019 template <class _Tp>
   1020 inline _LIBCPP_INLINE_VISIBILITY
   1021 bool
   1022 atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
   1023                                         _Tp __d,
   1024                                         memory_order __s, memory_order __f) _NOEXCEPT
   1025 {
   1026     return __o->compare_exchange_strong(*__e, __d, __s, __f);
   1027 }
   1028 
   1029 // atomic_fetch_add
   1030 
   1031 template <class _Tp>
   1032 inline _LIBCPP_INLINE_VISIBILITY
   1033 typename enable_if
   1034 <
   1035     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1036     _Tp
   1037 >::type
   1038 atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1039 {
   1040     return __o->fetch_add(__op);
   1041 }
   1042 
   1043 template <class _Tp>
   1044 inline _LIBCPP_INLINE_VISIBILITY
   1045 typename enable_if
   1046 <
   1047     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1048     _Tp
   1049 >::type
   1050 atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1051 {
   1052     return __o->fetch_add(__op);
   1053 }
   1054 
   1055 template <class _Tp>
   1056 inline _LIBCPP_INLINE_VISIBILITY
   1057 _Tp*
   1058 atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
   1059 {
   1060     return __o->fetch_add(__op);
   1061 }
   1062 
   1063 template <class _Tp>
   1064 inline _LIBCPP_INLINE_VISIBILITY
   1065 _Tp*
   1066 atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
   1067 {
   1068     return __o->fetch_add(__op);
   1069 }
   1070 
   1071 // atomic_fetch_add_explicit
   1072 
   1073 template <class _Tp>
   1074 inline _LIBCPP_INLINE_VISIBILITY
   1075 typename enable_if
   1076 <
   1077     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1078     _Tp
   1079 >::type
   1080 atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1081 {
   1082     return __o->fetch_add(__op, __m);
   1083 }
   1084 
   1085 template <class _Tp>
   1086 inline _LIBCPP_INLINE_VISIBILITY
   1087 typename enable_if
   1088 <
   1089     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1090     _Tp
   1091 >::type
   1092 atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1093 {
   1094     return __o->fetch_add(__op, __m);
   1095 }
   1096 
   1097 template <class _Tp>
   1098 inline _LIBCPP_INLINE_VISIBILITY
   1099 _Tp*
   1100 atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
   1101                           memory_order __m) _NOEXCEPT
   1102 {
   1103     return __o->fetch_add(__op, __m);
   1104 }
   1105 
   1106 template <class _Tp>
   1107 inline _LIBCPP_INLINE_VISIBILITY
   1108 _Tp*
   1109 atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
   1110 {
   1111     return __o->fetch_add(__op, __m);
   1112 }
   1113 
   1114 // atomic_fetch_sub
   1115 
   1116 template <class _Tp>
   1117 inline _LIBCPP_INLINE_VISIBILITY
   1118 typename enable_if
   1119 <
   1120     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1121     _Tp
   1122 >::type
   1123 atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1124 {
   1125     return __o->fetch_sub(__op);
   1126 }
   1127 
   1128 template <class _Tp>
   1129 inline _LIBCPP_INLINE_VISIBILITY
   1130 typename enable_if
   1131 <
   1132     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1133     _Tp
   1134 >::type
   1135 atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1136 {
   1137     return __o->fetch_sub(__op);
   1138 }
   1139 
   1140 template <class _Tp>
   1141 inline _LIBCPP_INLINE_VISIBILITY
   1142 _Tp*
   1143 atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
   1144 {
   1145     return __o->fetch_sub(__op);
   1146 }
   1147 
   1148 template <class _Tp>
   1149 inline _LIBCPP_INLINE_VISIBILITY
   1150 _Tp*
   1151 atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
   1152 {
   1153     return __o->fetch_sub(__op);
   1154 }
   1155 
   1156 // atomic_fetch_sub_explicit
   1157 
   1158 template <class _Tp>
   1159 inline _LIBCPP_INLINE_VISIBILITY
   1160 typename enable_if
   1161 <
   1162     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1163     _Tp
   1164 >::type
   1165 atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1166 {
   1167     return __o->fetch_sub(__op, __m);
   1168 }
   1169 
   1170 template <class _Tp>
   1171 inline _LIBCPP_INLINE_VISIBILITY
   1172 typename enable_if
   1173 <
   1174     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1175     _Tp
   1176 >::type
   1177 atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1178 {
   1179     return __o->fetch_sub(__op, __m);
   1180 }
   1181 
   1182 template <class _Tp>
   1183 inline _LIBCPP_INLINE_VISIBILITY
   1184 _Tp*
   1185 atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
   1186                           memory_order __m) _NOEXCEPT
   1187 {
   1188     return __o->fetch_sub(__op, __m);
   1189 }
   1190 
   1191 template <class _Tp>
   1192 inline _LIBCPP_INLINE_VISIBILITY
   1193 _Tp*
   1194 atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m) _NOEXCEPT
   1195 {
   1196     return __o->fetch_sub(__op, __m);
   1197 }
   1198 
   1199 // atomic_fetch_and
   1200 
   1201 template <class _Tp>
   1202 inline _LIBCPP_INLINE_VISIBILITY
   1203 typename enable_if
   1204 <
   1205     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1206     _Tp
   1207 >::type
   1208 atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1209 {
   1210     return __o->fetch_and(__op);
   1211 }
   1212 
   1213 template <class _Tp>
   1214 inline _LIBCPP_INLINE_VISIBILITY
   1215 typename enable_if
   1216 <
   1217     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1218     _Tp
   1219 >::type
   1220 atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1221 {
   1222     return __o->fetch_and(__op);
   1223 }
   1224 
   1225 // atomic_fetch_and_explicit
   1226 
   1227 template <class _Tp>
   1228 inline _LIBCPP_INLINE_VISIBILITY
   1229 typename enable_if
   1230 <
   1231     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1232     _Tp
   1233 >::type
   1234 atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1235 {
   1236     return __o->fetch_and(__op, __m);
   1237 }
   1238 
   1239 template <class _Tp>
   1240 inline _LIBCPP_INLINE_VISIBILITY
   1241 typename enable_if
   1242 <
   1243     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1244     _Tp
   1245 >::type
   1246 atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1247 {
   1248     return __o->fetch_and(__op, __m);
   1249 }
   1250 
   1251 // atomic_fetch_or
   1252 
   1253 template <class _Tp>
   1254 inline _LIBCPP_INLINE_VISIBILITY
   1255 typename enable_if
   1256 <
   1257     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1258     _Tp
   1259 >::type
   1260 atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1261 {
   1262     return __o->fetch_or(__op);
   1263 }
   1264 
   1265 template <class _Tp>
   1266 inline _LIBCPP_INLINE_VISIBILITY
   1267 typename enable_if
   1268 <
   1269     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1270     _Tp
   1271 >::type
   1272 atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1273 {
   1274     return __o->fetch_or(__op);
   1275 }
   1276 
   1277 // atomic_fetch_or_explicit
   1278 
   1279 template <class _Tp>
   1280 inline _LIBCPP_INLINE_VISIBILITY
   1281 typename enable_if
   1282 <
   1283     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1284     _Tp
   1285 >::type
   1286 atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1287 {
   1288     return __o->fetch_or(__op, __m);
   1289 }
   1290 
   1291 template <class _Tp>
   1292 inline _LIBCPP_INLINE_VISIBILITY
   1293 typename enable_if
   1294 <
   1295     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1296     _Tp
   1297 >::type
   1298 atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1299 {
   1300     return __o->fetch_or(__op, __m);
   1301 }
   1302 
   1303 // atomic_fetch_xor
   1304 
   1305 template <class _Tp>
   1306 inline _LIBCPP_INLINE_VISIBILITY
   1307 typename enable_if
   1308 <
   1309     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1310     _Tp
   1311 >::type
   1312 atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1313 {
   1314     return __o->fetch_xor(__op);
   1315 }
   1316 
   1317 template <class _Tp>
   1318 inline _LIBCPP_INLINE_VISIBILITY
   1319 typename enable_if
   1320 <
   1321     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1322     _Tp
   1323 >::type
   1324 atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
   1325 {
   1326     return __o->fetch_xor(__op);
   1327 }
   1328 
   1329 // atomic_fetch_xor_explicit
   1330 
   1331 template <class _Tp>
   1332 inline _LIBCPP_INLINE_VISIBILITY
   1333 typename enable_if
   1334 <
   1335     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1336     _Tp
   1337 >::type
   1338 atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1339 {
   1340     return __o->fetch_xor(__op, __m);
   1341 }
   1342 
   1343 template <class _Tp>
   1344 inline _LIBCPP_INLINE_VISIBILITY
   1345 typename enable_if
   1346 <
   1347     is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
   1348     _Tp
   1349 >::type
   1350 atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
   1351 {
   1352     return __o->fetch_xor(__op, __m);
   1353 }
   1354 
   1355 // flag type and operations
   1356 
   1357 typedef struct atomic_flag
   1358 {
   1359     _Atomic(bool) __a_;
   1360 
   1361     _LIBCPP_INLINE_VISIBILITY
   1362     bool test_and_set(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
   1363         {return __c11_atomic_exchange(&__a_, true, __m);}
   1364     _LIBCPP_INLINE_VISIBILITY
   1365     bool test_and_set(memory_order __m = memory_order_seq_cst) _NOEXCEPT
   1366         {return __c11_atomic_exchange(&__a_, true, __m);}
   1367     _LIBCPP_INLINE_VISIBILITY
   1368     void clear(memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
   1369         {__c11_atomic_store(&__a_, false, __m);}
   1370     _LIBCPP_INLINE_VISIBILITY
   1371     void clear(memory_order __m = memory_order_seq_cst) _NOEXCEPT
   1372         {__c11_atomic_store(&__a_, false, __m);}
   1373 
   1374     _LIBCPP_INLINE_VISIBILITY
   1375 #ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
   1376     atomic_flag() _NOEXCEPT = default;
   1377 #else
   1378     atomic_flag() _NOEXCEPT : __a_() {}
   1379 #endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
   1380 
   1381     _LIBCPP_INLINE_VISIBILITY
   1382     atomic_flag(bool __b) _NOEXCEPT : __a_(__b) {}
   1383 
   1384 #ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
   1385     atomic_flag(const atomic_flag&) = delete;
   1386     atomic_flag& operator=(const atomic_flag&) = delete;
   1387     atomic_flag& operator=(const atomic_flag&) volatile = delete;
   1388 #else  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
   1389 private:
   1390     atomic_flag(const atomic_flag&);
   1391     atomic_flag& operator=(const atomic_flag&);
   1392     atomic_flag& operator=(const atomic_flag&) volatile;
   1393 #endif  // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
   1394 } atomic_flag;
   1395 
   1396 inline _LIBCPP_INLINE_VISIBILITY
   1397 bool
   1398 atomic_flag_test_and_set(volatile atomic_flag* __o) _NOEXCEPT
   1399 {
   1400     return __o->test_and_set();
   1401 }
   1402 
   1403 inline _LIBCPP_INLINE_VISIBILITY
   1404 bool
   1405 atomic_flag_test_and_set(atomic_flag* __o) _NOEXCEPT
   1406 {
   1407     return __o->test_and_set();
   1408 }
   1409 
   1410 inline _LIBCPP_INLINE_VISIBILITY
   1411 bool
   1412 atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
   1413 {
   1414     return __o->test_and_set(__m);
   1415 }
   1416 
   1417 inline _LIBCPP_INLINE_VISIBILITY
   1418 bool
   1419 atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
   1420 {
   1421     return __o->test_and_set(__m);
   1422 }
   1423 
   1424 inline _LIBCPP_INLINE_VISIBILITY
   1425 void
   1426 atomic_flag_clear(volatile atomic_flag* __o) _NOEXCEPT
   1427 {
   1428     __o->clear();
   1429 }
   1430 
   1431 inline _LIBCPP_INLINE_VISIBILITY
   1432 void
   1433 atomic_flag_clear(atomic_flag* __o) _NOEXCEPT
   1434 {
   1435     __o->clear();
   1436 }
   1437 
   1438 inline _LIBCPP_INLINE_VISIBILITY
   1439 void
   1440 atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m) _NOEXCEPT
   1441 {
   1442     __o->clear(__m);
   1443 }
   1444 
   1445 inline _LIBCPP_INLINE_VISIBILITY
   1446 void
   1447 atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m) _NOEXCEPT
   1448 {
   1449     __o->clear(__m);
   1450 }
   1451 
   1452 // fences
   1453 
   1454 inline _LIBCPP_INLINE_VISIBILITY
   1455 void
   1456 atomic_thread_fence(memory_order __m) _NOEXCEPT
   1457 {
   1458     __c11_atomic_thread_fence(__m);
   1459 }
   1460 
   1461 inline _LIBCPP_INLINE_VISIBILITY
   1462 void
   1463 atomic_signal_fence(memory_order __m) _NOEXCEPT
   1464 {
   1465     __c11_atomic_signal_fence(__m);
   1466 }
   1467 
   1468 // Atomics for standard typedef types
   1469 
   1470 typedef atomic<bool>               atomic_bool;
   1471 typedef atomic<char>               atomic_char;
   1472 typedef atomic<signed char>        atomic_schar;
   1473 typedef atomic<unsigned char>      atomic_uchar;
   1474 typedef atomic<short>              atomic_short;
   1475 typedef atomic<unsigned short>     atomic_ushort;
   1476 typedef atomic<int>                atomic_int;
   1477 typedef atomic<unsigned int>       atomic_uint;
   1478 typedef atomic<long>               atomic_long;
   1479 typedef atomic<unsigned long>      atomic_ulong;
   1480 typedef atomic<long long>          atomic_llong;
   1481 typedef atomic<unsigned long long> atomic_ullong;
   1482 typedef atomic<char16_t>           atomic_char16_t;
   1483 typedef atomic<char32_t>           atomic_char32_t;
   1484 typedef atomic<wchar_t>            atomic_wchar_t;
   1485 
   1486 typedef atomic<int_least8_t>   atomic_int_least8_t;
   1487 typedef atomic<uint_least8_t>  atomic_uint_least8_t;
   1488 typedef atomic<int_least16_t>  atomic_int_least16_t;
   1489 typedef atomic<uint_least16_t> atomic_uint_least16_t;
   1490 typedef atomic<int_least32_t>  atomic_int_least32_t;
   1491 typedef atomic<uint_least32_t> atomic_uint_least32_t;
   1492 typedef atomic<int_least64_t>  atomic_int_least64_t;
   1493 typedef atomic<uint_least64_t> atomic_uint_least64_t;
   1494 
   1495 typedef atomic<int_fast8_t>   atomic_int_fast8_t;
   1496 typedef atomic<uint_fast8_t>  atomic_uint_fast8_t;
   1497 typedef atomic<int_fast16_t>  atomic_int_fast16_t;
   1498 typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
   1499 typedef atomic<int_fast32_t>  atomic_int_fast32_t;
   1500 typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
   1501 typedef atomic<int_fast64_t>  atomic_int_fast64_t;
   1502 typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
   1503 
   1504 typedef atomic<intptr_t>  atomic_intptr_t;
   1505 typedef atomic<uintptr_t> atomic_uintptr_t;
   1506 typedef atomic<size_t>    atomic_size_t;
   1507 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
   1508 typedef atomic<intmax_t>  atomic_intmax_t;
   1509 typedef atomic<uintmax_t> atomic_uintmax_t;
   1510 
   1511 #define ATOMIC_FLAG_INIT {false}
   1512 #define ATOMIC_VAR_INIT(__v) {__v}
   1513 
   1514 // lock-free property
   1515 
   1516 #define ATOMIC_BOOL_LOCK_FREE      __GCC_ATOMIC_BOOL_LOCK_FREE
   1517 #define ATOMIC_CHAR_LOCK_FREE      __GCC_ATOMIC_CHAR_LOCK_FREE
   1518 #define ATOMIC_CHAR16_T_LOCK_FREE  __GCC_ATOMIC_CHAR16_T_LOCK_FREE
   1519 #define ATOMIC_CHAR32_T_LOCK_FREE  __GCC_ATOMIC_CHAR32_T_LOCK_FREE
   1520 #define ATOMIC_WCHAR_T_LOCK_FREE   __GCC_ATOMIC_WCHAR_T_LOCK_FREE
   1521 #define ATOMIC_SHORT_LOCK_FREE     __GCC_ATOMIC_SHORT_LOCK_FREE
   1522 #define ATOMIC_INT_LOCK_FREE       __GCC_ATOMIC_INT_LOCK_FREE
   1523 #define ATOMIC_LONG_LOCK_FREE      __GCC_ATOMIC_LONG_LOCK_FREE
   1524 #define ATOMIC_LLONG_LOCK_FREE     __GCC_ATOMIC_LLONG_LOCK_FREE
   1525 #define ATOMIC_POINTER_LOCK_FREE   __GCC_ATOMIC_POINTER_LOCK_FREE
   1526 
   1527 #endif  //  !__has_feature(cxx_atomic)
   1528 
   1529 _LIBCPP_END_NAMESPACE_STD
   1530 
   1531 #endif  // _LIBCPP_ATOMIC
   1532