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