xref: /freebsd/contrib/llvm-project/libcxx/include/__atomic/atomic.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
106c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
206c3fb27SDimitry Andric //
306c3fb27SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406c3fb27SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
506c3fb27SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606c3fb27SDimitry Andric //
706c3fb27SDimitry Andric //===----------------------------------------------------------------------===//
806c3fb27SDimitry Andric 
906c3fb27SDimitry Andric #ifndef _LIBCPP___ATOMIC_ATOMIC_H
1006c3fb27SDimitry Andric #define _LIBCPP___ATOMIC_ATOMIC_H
1106c3fb27SDimitry Andric 
1206c3fb27SDimitry Andric #include <__atomic/atomic_base.h>
1306c3fb27SDimitry Andric #include <__atomic/check_memory_order.h>
1406c3fb27SDimitry Andric #include <__atomic/cxx_atomic_impl.h>
1506c3fb27SDimitry Andric #include <__atomic/memory_order.h>
1606c3fb27SDimitry Andric #include <__config>
175f757f3fSDimitry Andric #include <__functional/operations.h>
1806c3fb27SDimitry Andric #include <__memory/addressof.h>
195f757f3fSDimitry Andric #include <__type_traits/is_floating_point.h>
2006c3fb27SDimitry Andric #include <__type_traits/is_function.h>
2106c3fb27SDimitry Andric #include <__type_traits/is_same.h>
225f757f3fSDimitry Andric #include <__type_traits/remove_const.h>
2306c3fb27SDimitry Andric #include <__type_traits/remove_pointer.h>
245f757f3fSDimitry Andric #include <__type_traits/remove_volatile.h>
255f757f3fSDimitry Andric #include <__utility/forward.h>
2606c3fb27SDimitry Andric #include <cstddef>
275f757f3fSDimitry Andric #include <cstring>
2806c3fb27SDimitry Andric 
2906c3fb27SDimitry Andric #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
3006c3fb27SDimitry Andric #  pragma GCC system_header
3106c3fb27SDimitry Andric #endif
3206c3fb27SDimitry Andric 
3306c3fb27SDimitry Andric _LIBCPP_BEGIN_NAMESPACE_STD
3406c3fb27SDimitry Andric 
3506c3fb27SDimitry Andric template <class _Tp>
36cb14a3feSDimitry Andric struct atomic : public __atomic_base<_Tp> {
3706c3fb27SDimitry Andric   using __base          = __atomic_base<_Tp>;
3806c3fb27SDimitry Andric   using value_type      = _Tp;
3906c3fb27SDimitry Andric   using difference_type = value_type;
4006c3fb27SDimitry Andric 
4106c3fb27SDimitry Andric #if _LIBCPP_STD_VER >= 20
42cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI atomic() = default;
4306c3fb27SDimitry Andric #else
44cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default;
4506c3fb27SDimitry Andric #endif
4606c3fb27SDimitry Andric 
atomicatomic47cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic(_Tp __d) _NOEXCEPT : __base(__d) {}
4806c3fb27SDimitry Andric 
49cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile _NOEXCEPT {
50cb14a3feSDimitry Andric     __base::store(__d);
51cb14a3feSDimitry Andric     return __d;
52cb14a3feSDimitry Andric   }
53cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) _NOEXCEPT {
54cb14a3feSDimitry Andric     __base::store(__d);
55cb14a3feSDimitry Andric     return __d;
56cb14a3feSDimitry Andric   }
5706c3fb27SDimitry Andric 
5806c3fb27SDimitry Andric   atomic& operator=(const atomic&)          = delete;
5906c3fb27SDimitry Andric   atomic& operator=(const atomic&) volatile = delete;
6006c3fb27SDimitry Andric };
6106c3fb27SDimitry Andric 
6206c3fb27SDimitry Andric // atomic<T*>
6306c3fb27SDimitry Andric 
6406c3fb27SDimitry Andric template <class _Tp>
65cb14a3feSDimitry Andric struct atomic<_Tp*> : public __atomic_base<_Tp*> {
6606c3fb27SDimitry Andric   using __base          = __atomic_base<_Tp*>;
6706c3fb27SDimitry Andric   using value_type      = _Tp*;
6806c3fb27SDimitry Andric   using difference_type = ptrdiff_t;
6906c3fb27SDimitry Andric 
70cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI atomic() _NOEXCEPT = default;
7106c3fb27SDimitry Andric 
72cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR atomic(_Tp* __d) _NOEXCEPT : __base(__d) {}
7306c3fb27SDimitry Andric 
74cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) volatile _NOEXCEPT {
75cb14a3feSDimitry Andric     __base::store(__d);
76cb14a3feSDimitry Andric     return __d;
77cb14a3feSDimitry Andric   }
78cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator=(_Tp* __d) _NOEXCEPT {
79cb14a3feSDimitry Andric     __base::store(__d);
80cb14a3feSDimitry Andric     return __d;
81cb14a3feSDimitry Andric   }
8206c3fb27SDimitry Andric 
83cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
8406c3fb27SDimitry Andric     // __atomic_fetch_add accepts function pointers, guard against them.
8506c3fb27SDimitry Andric     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
8606c3fb27SDimitry Andric     return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
8706c3fb27SDimitry Andric   }
8806c3fb27SDimitry Andric 
89cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
9006c3fb27SDimitry Andric     // __atomic_fetch_add accepts function pointers, guard against them.
9106c3fb27SDimitry Andric     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
9206c3fb27SDimitry Andric     return std::__cxx_atomic_fetch_add(std::addressof(this->__a_), __op, __m);
9306c3fb27SDimitry Andric   }
9406c3fb27SDimitry Andric 
95cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
9606c3fb27SDimitry Andric     // __atomic_fetch_add accepts function pointers, guard against them.
9706c3fb27SDimitry Andric     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
9806c3fb27SDimitry Andric     return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
9906c3fb27SDimitry Andric   }
10006c3fb27SDimitry Andric 
101cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
10206c3fb27SDimitry Andric     // __atomic_fetch_add accepts function pointers, guard against them.
10306c3fb27SDimitry Andric     static_assert(!is_function<__remove_pointer_t<_Tp> >::value, "Pointer to function isn't allowed");
10406c3fb27SDimitry Andric     return std::__cxx_atomic_fetch_sub(std::addressof(this->__a_), __op, __m);
10506c3fb27SDimitry Andric   }
10606c3fb27SDimitry Andric 
107cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) volatile _NOEXCEPT { return fetch_add(1); }
108cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator++(int) _NOEXCEPT { return fetch_add(1); }
109cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) volatile _NOEXCEPT { return fetch_sub(1); }
110cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator--(int) _NOEXCEPT { return fetch_sub(1); }
111cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator++() volatile _NOEXCEPT { return fetch_add(1) + 1; }
112cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator++() _NOEXCEPT { return fetch_add(1) + 1; }
113cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator--() volatile _NOEXCEPT { return fetch_sub(1) - 1; }
114cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator--() _NOEXCEPT { return fetch_sub(1) - 1; }
115cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_add(__op) + __op; }
116cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator+=(ptrdiff_t __op) _NOEXCEPT { return fetch_add(__op) + __op; }
117cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) volatile _NOEXCEPT { return fetch_sub(__op) - __op; }
118cb14a3feSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp* operator-=(ptrdiff_t __op) _NOEXCEPT { return fetch_sub(__op) - __op; }
11906c3fb27SDimitry Andric 
12006c3fb27SDimitry Andric   atomic& operator=(const atomic&)          = delete;
12106c3fb27SDimitry Andric   atomic& operator=(const atomic&) volatile = delete;
12206c3fb27SDimitry Andric };
12306c3fb27SDimitry Andric 
1245f757f3fSDimitry Andric #if _LIBCPP_STD_VER >= 20
1255f757f3fSDimitry Andric template <class _Tp>
1265f757f3fSDimitry Andric   requires is_floating_point_v<_Tp>
1275f757f3fSDimitry Andric struct atomic<_Tp> : __atomic_base<_Tp> {
1285f757f3fSDimitry Andric private:
1295f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr bool __is_fp80_long_double() {
1305f757f3fSDimitry Andric     // Only x87-fp80 long double has 64-bit mantissa
1315f757f3fSDimitry Andric     return __LDBL_MANT_DIG__ == 64 && std::is_same_v<_Tp, long double>;
1325f757f3fSDimitry Andric   }
1335f757f3fSDimitry Andric 
1345f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static constexpr bool __has_rmw_builtin() {
1355f757f3fSDimitry Andric #  ifndef _LIBCPP_COMPILER_CLANG_BASED
1365f757f3fSDimitry Andric     return false;
1375f757f3fSDimitry Andric #  else
1385f757f3fSDimitry Andric     // The builtin __cxx_atomic_fetch_add errors during compilation for
1395f757f3fSDimitry Andric     // long double on platforms with fp80 format.
1405f757f3fSDimitry Andric     // For more details, see
1415f757f3fSDimitry Andric     // lib/Sema/SemaChecking.cpp function IsAllowedValueType
1425f757f3fSDimitry Andric     // LLVM Parser does not allow atomicrmw with x86_fp80 type.
1435f757f3fSDimitry Andric     // if (ValType->isSpecificBuiltinType(BuiltinType::LongDouble) &&
1445f757f3fSDimitry Andric     //    &Context.getTargetInfo().getLongDoubleFormat() ==
1455f757f3fSDimitry Andric     //        &llvm::APFloat::x87DoubleExtended())
1465f757f3fSDimitry Andric     // For more info
1475f757f3fSDimitry Andric     // https://github.com/llvm/llvm-project/issues/68602
1485f757f3fSDimitry Andric     // https://reviews.llvm.org/D53965
1495f757f3fSDimitry Andric     return !__is_fp80_long_double();
1505f757f3fSDimitry Andric #  endif
1515f757f3fSDimitry Andric   }
1525f757f3fSDimitry Andric 
1535f757f3fSDimitry Andric   template <class _This, class _Operation, class _BuiltinOp>
1545f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static _Tp
1555f757f3fSDimitry Andric   __rmw_op(_This&& __self, _Tp __operand, memory_order __m, _Operation __operation, _BuiltinOp __builtin_op) {
1565f757f3fSDimitry Andric     if constexpr (__has_rmw_builtin()) {
1575f757f3fSDimitry Andric       return __builtin_op(std::addressof(std::forward<_This>(__self).__a_), __operand, __m);
1585f757f3fSDimitry Andric     } else {
1595f757f3fSDimitry Andric       _Tp __old = __self.load(memory_order_relaxed);
1605f757f3fSDimitry Andric       _Tp __new = __operation(__old, __operand);
1615f757f3fSDimitry Andric       while (!__self.compare_exchange_weak(__old, __new, __m, memory_order_relaxed)) {
1625f757f3fSDimitry Andric #  ifdef _LIBCPP_COMPILER_CLANG_BASED
1635f757f3fSDimitry Andric         if constexpr (__is_fp80_long_double()) {
1645f757f3fSDimitry Andric           // https://github.com/llvm/llvm-project/issues/47978
1655f757f3fSDimitry Andric           // clang bug: __old is not updated on failure for atomic<long double>::compare_exchange_weak
1665f757f3fSDimitry Andric           // Note __old = __self.load(memory_order_relaxed) will not work
1675f757f3fSDimitry Andric           std::__cxx_atomic_load_inplace(std::addressof(__self.__a_), &__old, memory_order_relaxed);
1685f757f3fSDimitry Andric         }
1695f757f3fSDimitry Andric #  endif
1705f757f3fSDimitry Andric         __new = __operation(__old, __operand);
1715f757f3fSDimitry Andric       }
1725f757f3fSDimitry Andric       return __old;
1735f757f3fSDimitry Andric     }
1745f757f3fSDimitry Andric   }
1755f757f3fSDimitry Andric 
1765f757f3fSDimitry Andric   template <class _This>
1775f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_add(_This&& __self, _Tp __operand, memory_order __m) {
1785f757f3fSDimitry Andric     auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) {
1795f757f3fSDimitry Andric       return std::__cxx_atomic_fetch_add(__a, __builtin_operand, __order);
1805f757f3fSDimitry Andric     };
1815f757f3fSDimitry Andric     return __rmw_op(std::forward<_This>(__self), __operand, __m, std::plus<>{}, __builtin_op);
1825f757f3fSDimitry Andric   }
1835f757f3fSDimitry Andric 
1845f757f3fSDimitry Andric   template <class _This>
1855f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI static _Tp __fetch_sub(_This&& __self, _Tp __operand, memory_order __m) {
1865f757f3fSDimitry Andric     auto __builtin_op = [](auto __a, auto __builtin_operand, auto __order) {
1875f757f3fSDimitry Andric       return std::__cxx_atomic_fetch_sub(__a, __builtin_operand, __order);
1885f757f3fSDimitry Andric     };
1895f757f3fSDimitry Andric     return __rmw_op(std::forward<_This>(__self), __operand, __m, std::minus<>{}, __builtin_op);
1905f757f3fSDimitry Andric   }
1915f757f3fSDimitry Andric 
1925f757f3fSDimitry Andric public:
1935f757f3fSDimitry Andric   using __base          = __atomic_base<_Tp>;
1945f757f3fSDimitry Andric   using value_type      = _Tp;
1955f757f3fSDimitry Andric   using difference_type = value_type;
1965f757f3fSDimitry Andric 
1975f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr atomic() noexcept = default;
1985f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI constexpr atomic(_Tp __d) noexcept : __base(__d) {}
1995f757f3fSDimitry Andric 
2005f757f3fSDimitry Andric   atomic(const atomic&)                     = delete;
2015f757f3fSDimitry Andric   atomic& operator=(const atomic&)          = delete;
2025f757f3fSDimitry Andric   atomic& operator=(const atomic&) volatile = delete;
2035f757f3fSDimitry Andric 
2045f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) volatile noexcept
2055f757f3fSDimitry Andric     requires __base::is_always_lock_free
2065f757f3fSDimitry Andric   {
2075f757f3fSDimitry Andric     __base::store(__d);
2085f757f3fSDimitry Andric     return __d;
2095f757f3fSDimitry Andric   }
2105f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __d) noexcept {
2115f757f3fSDimitry Andric     __base::store(__d);
2125f757f3fSDimitry Andric     return __d;
2135f757f3fSDimitry Andric   }
2145f757f3fSDimitry Andric 
2155f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept
2165f757f3fSDimitry Andric     requires __base::is_always_lock_free
2175f757f3fSDimitry Andric   {
2185f757f3fSDimitry Andric     return __fetch_add(*this, __op, __m);
2195f757f3fSDimitry Andric   }
2205f757f3fSDimitry Andric 
2215f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept {
2225f757f3fSDimitry Andric     return __fetch_add(*this, __op, __m);
2235f757f3fSDimitry Andric   }
2245f757f3fSDimitry Andric 
2255f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile noexcept
2265f757f3fSDimitry Andric     requires __base::is_always_lock_free
2275f757f3fSDimitry Andric   {
2285f757f3fSDimitry Andric     return __fetch_sub(*this, __op, __m);
2295f757f3fSDimitry Andric   }
2305f757f3fSDimitry Andric 
2315f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) noexcept {
2325f757f3fSDimitry Andric     return __fetch_sub(*this, __op, __m);
2335f757f3fSDimitry Andric   }
2345f757f3fSDimitry Andric 
2355f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) volatile noexcept
2365f757f3fSDimitry Andric     requires __base::is_always_lock_free
2375f757f3fSDimitry Andric   {
2385f757f3fSDimitry Andric     return fetch_add(__op) + __op;
2395f757f3fSDimitry Andric   }
2405f757f3fSDimitry Andric 
2415f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __op) noexcept { return fetch_add(__op) + __op; }
2425f757f3fSDimitry Andric 
2435f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) volatile noexcept
2445f757f3fSDimitry Andric     requires __base::is_always_lock_free
2455f757f3fSDimitry Andric   {
2465f757f3fSDimitry Andric     return fetch_sub(__op) - __op;
2475f757f3fSDimitry Andric   }
2485f757f3fSDimitry Andric 
2495f757f3fSDimitry Andric   _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __op) noexcept { return fetch_sub(__op) - __op; }
2505f757f3fSDimitry Andric };
2515f757f3fSDimitry Andric 
2525f757f3fSDimitry Andric #endif // _LIBCPP_STD_VER >= 20
2535f757f3fSDimitry Andric 
25406c3fb27SDimitry Andric // atomic_is_lock_free
25506c3fb27SDimitry Andric 
25606c3fb27SDimitry Andric template <class _Tp>
257cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const volatile atomic<_Tp>* __o) _NOEXCEPT {
25806c3fb27SDimitry Andric   return __o->is_lock_free();
25906c3fb27SDimitry Andric }
26006c3fb27SDimitry Andric 
26106c3fb27SDimitry Andric template <class _Tp>
262cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT {
26306c3fb27SDimitry Andric   return __o->is_lock_free();
26406c3fb27SDimitry Andric }
26506c3fb27SDimitry Andric 
26606c3fb27SDimitry Andric // atomic_init
26706c3fb27SDimitry Andric 
26806c3fb27SDimitry Andric template <class _Tp>
269cb14a3feSDimitry Andric _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void
270cb14a3feSDimitry Andric atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
27106c3fb27SDimitry Andric   std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
27206c3fb27SDimitry Andric }
27306c3fb27SDimitry Andric 
27406c3fb27SDimitry Andric template <class _Tp>
275cb14a3feSDimitry Andric _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI void
276cb14a3feSDimitry Andric atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
27706c3fb27SDimitry Andric   std::__cxx_atomic_init(std::addressof(__o->__a_), __d);
27806c3fb27SDimitry Andric }
27906c3fb27SDimitry Andric 
28006c3fb27SDimitry Andric // atomic_store
28106c3fb27SDimitry Andric 
28206c3fb27SDimitry Andric template <class _Tp>
283cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
28406c3fb27SDimitry Andric   __o->store(__d);
28506c3fb27SDimitry Andric }
28606c3fb27SDimitry Andric 
28706c3fb27SDimitry Andric template <class _Tp>
288cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
28906c3fb27SDimitry Andric   __o->store(__d);
29006c3fb27SDimitry Andric }
29106c3fb27SDimitry Andric 
29206c3fb27SDimitry Andric // atomic_store_explicit
29306c3fb27SDimitry Andric 
29406c3fb27SDimitry Andric template <class _Tp>
295cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void
29606c3fb27SDimitry Andric atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
297cb14a3feSDimitry Andric     _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
29806c3fb27SDimitry Andric   __o->store(__d, __m);
29906c3fb27SDimitry Andric }
30006c3fb27SDimitry Andric 
30106c3fb27SDimitry Andric template <class _Tp>
302cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI void
30306c3fb27SDimitry Andric atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
304cb14a3feSDimitry Andric     _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
30506c3fb27SDimitry Andric   __o->store(__d, __m);
30606c3fb27SDimitry Andric }
30706c3fb27SDimitry Andric 
30806c3fb27SDimitry Andric // atomic_load
30906c3fb27SDimitry Andric 
31006c3fb27SDimitry Andric template <class _Tp>
311cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const volatile atomic<_Tp>* __o) _NOEXCEPT {
31206c3fb27SDimitry Andric   return __o->load();
31306c3fb27SDimitry Andric }
31406c3fb27SDimitry Andric 
31506c3fb27SDimitry Andric template <class _Tp>
316cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_load(const atomic<_Tp>* __o) _NOEXCEPT {
31706c3fb27SDimitry Andric   return __o->load();
31806c3fb27SDimitry Andric }
31906c3fb27SDimitry Andric 
32006c3fb27SDimitry Andric // atomic_load_explicit
32106c3fb27SDimitry Andric 
32206c3fb27SDimitry Andric template <class _Tp>
323cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
324cb14a3feSDimitry Andric     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
32506c3fb27SDimitry Andric   return __o->load(__m);
32606c3fb27SDimitry Andric }
32706c3fb27SDimitry Andric 
32806c3fb27SDimitry Andric template <class _Tp>
329cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
330cb14a3feSDimitry Andric     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
33106c3fb27SDimitry Andric   return __o->load(__m);
33206c3fb27SDimitry Andric }
33306c3fb27SDimitry Andric 
33406c3fb27SDimitry Andric // atomic_exchange
33506c3fb27SDimitry Andric 
33606c3fb27SDimitry Andric template <class _Tp>
337cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
33806c3fb27SDimitry Andric   return __o->exchange(__d);
33906c3fb27SDimitry Andric }
34006c3fb27SDimitry Andric 
34106c3fb27SDimitry Andric template <class _Tp>
342cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
34306c3fb27SDimitry Andric   return __o->exchange(__d);
34406c3fb27SDimitry Andric }
34506c3fb27SDimitry Andric 
34606c3fb27SDimitry Andric // atomic_exchange_explicit
34706c3fb27SDimitry Andric 
34806c3fb27SDimitry Andric template <class _Tp>
349cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
350cb14a3feSDimitry Andric atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT {
35106c3fb27SDimitry Andric   return __o->exchange(__d, __m);
35206c3fb27SDimitry Andric }
35306c3fb27SDimitry Andric 
35406c3fb27SDimitry Andric template <class _Tp>
355cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
356cb14a3feSDimitry Andric atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT {
35706c3fb27SDimitry Andric   return __o->exchange(__d, __m);
35806c3fb27SDimitry Andric }
35906c3fb27SDimitry Andric 
36006c3fb27SDimitry Andric // atomic_compare_exchange_weak
36106c3fb27SDimitry Andric 
36206c3fb27SDimitry Andric template <class _Tp>
363cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak(
364cb14a3feSDimitry Andric     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
36506c3fb27SDimitry Andric   return __o->compare_exchange_weak(*__e, __d);
36606c3fb27SDimitry Andric }
36706c3fb27SDimitry Andric 
36806c3fb27SDimitry Andric template <class _Tp>
369cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak(
370cb14a3feSDimitry Andric     atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
37106c3fb27SDimitry Andric   return __o->compare_exchange_weak(*__e, __d);
37206c3fb27SDimitry Andric }
37306c3fb27SDimitry Andric 
37406c3fb27SDimitry Andric // atomic_compare_exchange_strong
37506c3fb27SDimitry Andric 
37606c3fb27SDimitry Andric template <class _Tp>
377cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong(
378cb14a3feSDimitry Andric     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
37906c3fb27SDimitry Andric   return __o->compare_exchange_strong(*__e, __d);
38006c3fb27SDimitry Andric }
38106c3fb27SDimitry Andric 
38206c3fb27SDimitry Andric template <class _Tp>
383cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong(
384cb14a3feSDimitry Andric     atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT {
38506c3fb27SDimitry Andric   return __o->compare_exchange_strong(*__e, __d);
38606c3fb27SDimitry Andric }
38706c3fb27SDimitry Andric 
38806c3fb27SDimitry Andric // atomic_compare_exchange_weak_explicit
38906c3fb27SDimitry Andric 
39006c3fb27SDimitry Andric template <class _Tp>
391cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit(
392cb14a3feSDimitry Andric     volatile atomic<_Tp>* __o,
393cb14a3feSDimitry Andric     typename atomic<_Tp>::value_type* __e,
39406c3fb27SDimitry Andric     typename atomic<_Tp>::value_type __d,
395cb14a3feSDimitry Andric     memory_order __s,
396cb14a3feSDimitry Andric     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
39706c3fb27SDimitry Andric   return __o->compare_exchange_weak(*__e, __d, __s, __f);
39806c3fb27SDimitry Andric }
39906c3fb27SDimitry Andric 
40006c3fb27SDimitry Andric template <class _Tp>
401cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_weak_explicit(
402cb14a3feSDimitry Andric     atomic<_Tp>* __o,
403cb14a3feSDimitry Andric     typename atomic<_Tp>::value_type* __e,
404cb14a3feSDimitry Andric     typename atomic<_Tp>::value_type __d,
405cb14a3feSDimitry Andric     memory_order __s,
406cb14a3feSDimitry Andric     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
40706c3fb27SDimitry Andric   return __o->compare_exchange_weak(*__e, __d, __s, __f);
40806c3fb27SDimitry Andric }
40906c3fb27SDimitry Andric 
41006c3fb27SDimitry Andric // atomic_compare_exchange_strong_explicit
41106c3fb27SDimitry Andric 
41206c3fb27SDimitry Andric template <class _Tp>
413cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
414cb14a3feSDimitry Andric     volatile atomic<_Tp>* __o,
415cb14a3feSDimitry Andric     typename atomic<_Tp>::value_type* __e,
416cb14a3feSDimitry Andric     typename atomic<_Tp>::value_type __d,
417cb14a3feSDimitry Andric     memory_order __s,
418cb14a3feSDimitry Andric     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
41906c3fb27SDimitry Andric   return __o->compare_exchange_strong(*__e, __d, __s, __f);
42006c3fb27SDimitry Andric }
42106c3fb27SDimitry Andric 
42206c3fb27SDimitry Andric template <class _Tp>
423cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI bool atomic_compare_exchange_strong_explicit(
424cb14a3feSDimitry Andric     atomic<_Tp>* __o,
425cb14a3feSDimitry Andric     typename atomic<_Tp>::value_type* __e,
42606c3fb27SDimitry Andric     typename atomic<_Tp>::value_type __d,
427cb14a3feSDimitry Andric     memory_order __s,
428cb14a3feSDimitry Andric     memory_order __f) _NOEXCEPT _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f) {
42906c3fb27SDimitry Andric   return __o->compare_exchange_strong(*__e, __d, __s, __f);
43006c3fb27SDimitry Andric }
43106c3fb27SDimitry Andric 
43206c3fb27SDimitry Andric // atomic_wait
43306c3fb27SDimitry Andric 
43406c3fb27SDimitry Andric template <class _Tp>
435cb14a3feSDimitry Andric _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
436cb14a3feSDimitry Andric atomic_wait(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
43706c3fb27SDimitry Andric   return __o->wait(__v);
43806c3fb27SDimitry Andric }
43906c3fb27SDimitry Andric 
44006c3fb27SDimitry Andric template <class _Tp>
441cb14a3feSDimitry Andric _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
442cb14a3feSDimitry Andric atomic_wait(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v) _NOEXCEPT {
44306c3fb27SDimitry Andric   return __o->wait(__v);
44406c3fb27SDimitry Andric }
44506c3fb27SDimitry Andric 
44606c3fb27SDimitry Andric // atomic_wait_explicit
44706c3fb27SDimitry Andric 
44806c3fb27SDimitry Andric template <class _Tp>
449cb14a3feSDimitry Andric _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
450cb14a3feSDimitry Andric atomic_wait_explicit(const volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
451cb14a3feSDimitry Andric     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
45206c3fb27SDimitry Andric   return __o->wait(__v, __m);
45306c3fb27SDimitry Andric }
45406c3fb27SDimitry Andric 
45506c3fb27SDimitry Andric template <class _Tp>
456cb14a3feSDimitry Andric _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
457cb14a3feSDimitry Andric atomic_wait_explicit(const atomic<_Tp>* __o, typename atomic<_Tp>::value_type __v, memory_order __m) _NOEXCEPT
458cb14a3feSDimitry Andric     _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
45906c3fb27SDimitry Andric   return __o->wait(__v, __m);
46006c3fb27SDimitry Andric }
46106c3fb27SDimitry Andric 
46206c3fb27SDimitry Andric // atomic_notify_one
46306c3fb27SDimitry Andric 
46406c3fb27SDimitry Andric template <class _Tp>
465*0fca6ea1SDimitry Andric _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
466*0fca6ea1SDimitry Andric atomic_notify_one(volatile atomic<_Tp>* __o) _NOEXCEPT {
46706c3fb27SDimitry Andric   __o->notify_one();
46806c3fb27SDimitry Andric }
46906c3fb27SDimitry Andric template <class _Tp>
470*0fca6ea1SDimitry Andric _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
471*0fca6ea1SDimitry Andric atomic_notify_one(atomic<_Tp>* __o) _NOEXCEPT {
47206c3fb27SDimitry Andric   __o->notify_one();
47306c3fb27SDimitry Andric }
47406c3fb27SDimitry Andric 
47506c3fb27SDimitry Andric // atomic_notify_all
47606c3fb27SDimitry Andric 
47706c3fb27SDimitry Andric template <class _Tp>
478*0fca6ea1SDimitry Andric _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
479*0fca6ea1SDimitry Andric atomic_notify_all(volatile atomic<_Tp>* __o) _NOEXCEPT {
48006c3fb27SDimitry Andric   __o->notify_all();
48106c3fb27SDimitry Andric }
48206c3fb27SDimitry Andric template <class _Tp>
483*0fca6ea1SDimitry Andric _LIBCPP_DEPRECATED_ATOMIC_SYNC _LIBCPP_AVAILABILITY_SYNC _LIBCPP_HIDE_FROM_ABI void
484*0fca6ea1SDimitry Andric atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT {
48506c3fb27SDimitry Andric   __o->notify_all();
48606c3fb27SDimitry Andric }
48706c3fb27SDimitry Andric 
48806c3fb27SDimitry Andric // atomic_fetch_add
48906c3fb27SDimitry Andric 
49006c3fb27SDimitry Andric template <class _Tp>
491cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
492cb14a3feSDimitry Andric atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
49306c3fb27SDimitry Andric   return __o->fetch_add(__op);
49406c3fb27SDimitry Andric }
49506c3fb27SDimitry Andric 
49606c3fb27SDimitry Andric template <class _Tp>
497cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
49806c3fb27SDimitry Andric   return __o->fetch_add(__op);
49906c3fb27SDimitry Andric }
50006c3fb27SDimitry Andric 
50106c3fb27SDimitry Andric // atomic_fetch_add_explicit
50206c3fb27SDimitry Andric 
50306c3fb27SDimitry Andric template <class _Tp>
504cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_add_explicit(
505cb14a3feSDimitry Andric     volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
50606c3fb27SDimitry Andric   return __o->fetch_add(__op, __m);
50706c3fb27SDimitry Andric }
50806c3fb27SDimitry Andric 
50906c3fb27SDimitry Andric template <class _Tp>
510cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
511cb14a3feSDimitry Andric atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
51206c3fb27SDimitry Andric   return __o->fetch_add(__op, __m);
51306c3fb27SDimitry Andric }
51406c3fb27SDimitry Andric 
51506c3fb27SDimitry Andric // atomic_fetch_sub
51606c3fb27SDimitry Andric 
51706c3fb27SDimitry Andric template <class _Tp>
518cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
519cb14a3feSDimitry Andric atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
52006c3fb27SDimitry Andric   return __o->fetch_sub(__op);
52106c3fb27SDimitry Andric }
52206c3fb27SDimitry Andric 
52306c3fb27SDimitry Andric template <class _Tp>
524cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT {
52506c3fb27SDimitry Andric   return __o->fetch_sub(__op);
52606c3fb27SDimitry Andric }
52706c3fb27SDimitry Andric 
52806c3fb27SDimitry Andric // atomic_fetch_sub_explicit
52906c3fb27SDimitry Andric 
53006c3fb27SDimitry Andric template <class _Tp>
531cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_sub_explicit(
532cb14a3feSDimitry Andric     volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
53306c3fb27SDimitry Andric   return __o->fetch_sub(__op, __m);
53406c3fb27SDimitry Andric }
53506c3fb27SDimitry Andric 
53606c3fb27SDimitry Andric template <class _Tp>
537cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
538cb14a3feSDimitry Andric atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT {
53906c3fb27SDimitry Andric   return __o->fetch_sub(__op, __m);
54006c3fb27SDimitry Andric }
54106c3fb27SDimitry Andric 
54206c3fb27SDimitry Andric // atomic_fetch_and
54306c3fb27SDimitry Andric 
5445f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
545cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
54606c3fb27SDimitry Andric   return __o->fetch_and(__op);
54706c3fb27SDimitry Andric }
54806c3fb27SDimitry Andric 
5495f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
550cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
55106c3fb27SDimitry Andric   return __o->fetch_and(__op);
55206c3fb27SDimitry Andric }
55306c3fb27SDimitry Andric 
55406c3fb27SDimitry Andric // atomic_fetch_and_explicit
55506c3fb27SDimitry Andric 
5565f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
557cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_and_explicit(
558cb14a3feSDimitry Andric     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
55906c3fb27SDimitry Andric   return __o->fetch_and(__op, __m);
56006c3fb27SDimitry Andric }
56106c3fb27SDimitry Andric 
5625f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
563cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
564cb14a3feSDimitry Andric atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
56506c3fb27SDimitry Andric   return __o->fetch_and(__op, __m);
56606c3fb27SDimitry Andric }
56706c3fb27SDimitry Andric 
56806c3fb27SDimitry Andric // atomic_fetch_or
56906c3fb27SDimitry Andric 
5705f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
571cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
57206c3fb27SDimitry Andric   return __o->fetch_or(__op);
57306c3fb27SDimitry Andric }
57406c3fb27SDimitry Andric 
5755f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
576cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
57706c3fb27SDimitry Andric   return __o->fetch_or(__op);
57806c3fb27SDimitry Andric }
57906c3fb27SDimitry Andric 
58006c3fb27SDimitry Andric // atomic_fetch_or_explicit
58106c3fb27SDimitry Andric 
5825f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
583cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
584cb14a3feSDimitry Andric atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
58506c3fb27SDimitry Andric   return __o->fetch_or(__op, __m);
58606c3fb27SDimitry Andric }
58706c3fb27SDimitry Andric 
5885f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
589cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
590cb14a3feSDimitry Andric atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
59106c3fb27SDimitry Andric   return __o->fetch_or(__op, __m);
59206c3fb27SDimitry Andric }
59306c3fb27SDimitry Andric 
59406c3fb27SDimitry Andric // atomic_fetch_xor
59506c3fb27SDimitry Andric 
5965f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
597cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
59806c3fb27SDimitry Andric   return __o->fetch_xor(__op);
59906c3fb27SDimitry Andric }
60006c3fb27SDimitry Andric 
6015f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
602cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT {
60306c3fb27SDimitry Andric   return __o->fetch_xor(__op);
60406c3fb27SDimitry Andric }
60506c3fb27SDimitry Andric 
60606c3fb27SDimitry Andric // atomic_fetch_xor_explicit
60706c3fb27SDimitry Andric 
6085f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
609cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp atomic_fetch_xor_explicit(
610cb14a3feSDimitry Andric     volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
61106c3fb27SDimitry Andric   return __o->fetch_xor(__op, __m);
61206c3fb27SDimitry Andric }
61306c3fb27SDimitry Andric 
6145f757f3fSDimitry Andric template <class _Tp, __enable_if_t<is_integral<_Tp>::value && !is_same<_Tp, bool>::value, int> = 0>
615cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI _Tp
616cb14a3feSDimitry Andric atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT {
61706c3fb27SDimitry Andric   return __o->fetch_xor(__op, __m);
61806c3fb27SDimitry Andric }
61906c3fb27SDimitry Andric 
62006c3fb27SDimitry Andric _LIBCPP_END_NAMESPACE_STD
62106c3fb27SDimitry Andric 
62206c3fb27SDimitry Andric #endif // _LIBCPP___ATOMIC_ATOMIC_H
623