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