diff options
Diffstat (limited to 'libcxx/include/atomic')
| -rw-r--r-- | libcxx/include/atomic | 509 |
1 files changed, 189 insertions, 320 deletions
diff --git a/libcxx/include/atomic b/libcxx/include/atomic index 0f6aee83ce82..cfd0e1d054a8 100644 --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -1,5 +1,5 @@ // -*- C++ -*- -//===--------------------------- atomic -----------------------------------===// +//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -263,196 +263,137 @@ struct atomic<T*> }; -template <class T> - bool atomic_is_lock_free(const volatile atomic<T>* obj) noexcept; - -template <class T> - bool atomic_is_lock_free(const atomic<T>* obj) noexcept; - -template <class T> - void atomic_store(volatile atomic<T>* obj, T desr) noexcept; - -template <class T> - void atomic_store(atomic<T>* obj, T desr) noexcept; - -template <class T> - void atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; - -template <class T> - void atomic_store_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; - -template <class T> - T atomic_load(const volatile atomic<T>* obj) noexcept; - -template <class T> - T atomic_load(const atomic<T>* obj) noexcept; - -template <class T> - T atomic_load_explicit(const volatile atomic<T>* obj, memory_order m) noexcept; - -template <class T> - T atomic_load_explicit(const atomic<T>* obj, memory_order m) noexcept; - -template <class T> - T atomic_exchange(volatile atomic<T>* obj, T desr) noexcept; - -template <class T> - T atomic_exchange(atomic<T>* obj, T desr) noexcept; - -template <class T> - T atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m) noexcept; - -template <class T> - T atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m) noexcept; +// [atomics.nonmembers], non-member functions +template<class T> + bool atomic_is_lock_free(const volatile atomic<T>*) noexcept; +template<class T> + bool atomic_is_lock_free(const atomic<T>*) noexcept; +template<class T> + void atomic_store(volatile atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + void atomic_store(atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + void atomic_store_explicit(volatile atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; +template<class T> + void atomic_store_explicit(atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; +template<class T> + T atomic_load(const volatile atomic<T>*) noexcept; +template<class T> + T atomic_load(const atomic<T>*) noexcept; +template<class T> + T atomic_load_explicit(const volatile atomic<T>*, memory_order) noexcept; +template<class T> + T atomic_load_explicit(const atomic<T>*, memory_order) noexcept; +template<class T> + T atomic_exchange(volatile atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + T atomic_exchange(atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + T atomic_exchange_explicit(volatile atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; +template<class T> + T atomic_exchange_explicit(atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; +template<class T> + bool atomic_compare_exchange_weak(volatile atomic<T>*, atomic<T>::value_type*, + atomic<T>::value_type) noexcept; +template<class T> + bool atomic_compare_exchange_weak(atomic<T>*, atomic<T>::value_type*, + atomic<T>::value_type) noexcept; +template<class T> + bool atomic_compare_exchange_strong(volatile atomic<T>*, atomic<T>::value_type*, + atomic<T>::value_type) noexcept; +template<class T> + bool atomic_compare_exchange_strong(atomic<T>*, atomic<T>::value_type*, + atomic<T>::value_type) noexcept; +template<class T> + bool atomic_compare_exchange_weak_explicit(volatile atomic<T>*, atomic<T>::value_type*, + atomic<T>::value_type, + memory_order, memory_order) noexcept; +template<class T> + bool atomic_compare_exchange_weak_explicit(atomic<T>*, atomic<T>::value_type*, + atomic<T>::value_type, + memory_order, memory_order) noexcept; +template<class T> + bool atomic_compare_exchange_strong_explicit(volatile atomic<T>*, atomic<T>::value_type*, + atomic<T>::value_type, + memory_order, memory_order) noexcept; +template<class T> + bool atomic_compare_exchange_strong_explicit(atomic<T>*, atomic<T>::value_type*, + atomic<T>::value_type, + memory_order, memory_order) noexcept; -template <class T> - bool atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr) noexcept; +template<class T> + T atomic_fetch_add(volatile atomic<T>*, atomic<T>::difference_type) noexcept; +template<class T> + T atomic_fetch_add(atomic<T>*, atomic<T>::difference_type) noexcept; +template<class T> + T atomic_fetch_add_explicit(volatile atomic<T>*, atomic<T>::difference_type, + memory_order) noexcept; +template<class T> + T atomic_fetch_add_explicit(atomic<T>*, atomic<T>::difference_type, + memory_order) noexcept; +template<class T> + T atomic_fetch_sub(volatile atomic<T>*, atomic<T>::difference_type) noexcept; +template<class T> + T atomic_fetch_sub(atomic<T>*, atomic<T>::difference_type) noexcept; +template<class T> + T atomic_fetch_sub_explicit(volatile atomic<T>*, atomic<T>::difference_type, + memory_order) noexcept; +template<class T> + T atomic_fetch_sub_explicit(atomic<T>*, atomic<T>::difference_type, + memory_order) noexcept; +template<class T> + T atomic_fetch_and(volatile atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + T atomic_fetch_and(atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + T atomic_fetch_and_explicit(volatile atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; +template<class T> + T atomic_fetch_and_explicit(atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; +template<class T> + T atomic_fetch_or(volatile atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + T atomic_fetch_or(atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + T atomic_fetch_or_explicit(volatile atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; +template<class T> + T atomic_fetch_or_explicit(atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; +template<class T> + T atomic_fetch_xor(volatile atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + T atomic_fetch_xor(atomic<T>*, atomic<T>::value_type) noexcept; +template<class T> + T atomic_fetch_xor_explicit(volatile atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; +template<class T> + T atomic_fetch_xor_explicit(atomic<T>*, atomic<T>::value_type, + memory_order) noexcept; -template <class T> - bool atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr) noexcept; - -template <class T> - bool atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr) noexcept; - -template <class T> - bool atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr) noexcept; - -template <class T> - bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc, - T desr, - memory_order s, memory_order f) noexcept; - -template <class T> - bool atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr, - memory_order s, memory_order f) noexcept; - -template <class T> - bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj, - T* expc, T desr, - memory_order s, memory_order f) noexcept; - -template <class T> - bool atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc, - T desr, - memory_order s, memory_order f) noexcept; - -template <class T> - void atomic_wait(const volatile atomic<T>* obj, T old) noexcept; - -template <class T> - void atomic_wait(const atomic<T>* obj, T old) noexcept; - -template <class T> - void atomic_wait_explicit(const volatile atomic<T>* obj, T old, memory_order m) noexcept; - -template <class T> - void atomic_wait_explicit(const atomic<T>* obj, T old, memory_order m) noexcept; - -template <class T> - void atomic_one(volatile atomic<T>* obj) noexcept; - -template <class T> - void atomic_one(atomic<T>* obj) noexcept; - -template <class T> - void atomic_all(volatile atomic<T>* obj) noexcept; - -template <class T> - void atomic_all(atomic<T>* obj) noexcept; - -template <class Integral> - Integral atomic_fetch_add(volatile atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_add(atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op, - memory_order m) noexcept; -template <class Integral> - Integral atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op, - memory_order m) noexcept; -template <class Integral> - Integral atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_sub(atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op, - memory_order m) noexcept; - -template <class Integral> - Integral atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op, - memory_order m) noexcept; - -template <class Integral> - Integral atomic_fetch_and(volatile atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_and(atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op, - memory_order m) noexcept; - -template <class Integral> - Integral atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op, - memory_order m) noexcept; - -template <class Integral> - Integral atomic_fetch_or(volatile atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_or(atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op, - memory_order m) noexcept; - -template <class Integral> - Integral atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op, - memory_order m) noexcept; - -template <class Integral> - Integral atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_xor(atomic<Integral>* obj, Integral op) noexcept; - -template <class Integral> - Integral atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op, - memory_order m) noexcept; - -template <class Integral> - Integral atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op, - memory_order m) noexcept; - -template <class T> - T* atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; - -template <class T> - T* atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op) noexcept; - -template <class T> - T* atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op, - memory_order m) noexcept; - -template <class T> - T* atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; - -template <class T> - T* atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op) noexcept; - -template <class T> - T* atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op) noexcept; - -template <class T> - T* atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op, - memory_order m) noexcept; - -template <class T> - T* atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m) noexcept; +template<class T> + void atomic_wait(const volatile atomic<T>*, atomic<T>::value_type); +template<class T> + void atomic_wait(const atomic<T>*, atomic<T>::value_type); +template<class T> + void atomic_wait_explicit(const volatile atomic<T>*, atomic<T>::value_type, + memory_order); +template<class T> + void atomic_wait_explicit(const atomic<T>*, atomic<T>::value_type, + memory_order); +template<class T> + void atomic_notify_one(volatile atomic<T>*); +template<class T> + void atomic_notify_one(atomic<T>*); +template<class T> + void atomic_notify_all(volatile atomic<T>*); +template<class T> + void atomic_notify_all(atomic<T>*); // Atomics for standard typedef types @@ -564,10 +505,10 @@ void atomic_signal_fence(memory_order m) noexcept; // deprecated template <class T> - void atomic_init(volatile atomic<T>* obj, typename atomic<T>::value_type desr) noexcept; + void atomic_init(volatile atomic<T>* obj, atomic<T>::value_type desr) noexcept; template <class T> - void atomic_init(atomic<T>* obj, typename atomic<T>::value_type desr) noexcept; + void atomic_init(atomic<T>* obj, atomic<T>::value_type desr) noexcept; #define ATOMIC_VAR_INIT(value) see below @@ -579,20 +520,21 @@ template <class T> #include <__availability> #include <__config> -#include <__threading_support> +#include <__thread/poll_with_backoff.h> #include <cstddef> #include <cstdint> #include <cstring> #include <type_traits> #include <version> +#ifndef _LIBCPP_HAS_NO_THREADS +# include <__threading_support> +#endif + #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) #pragma GCC system_header #endif -#ifdef _LIBCPP_HAS_NO_THREADS -# error <atomic> is not supported on this single threaded system -#endif #ifdef _LIBCPP_HAS_NO_ATOMIC_HEADER # error <atomic> is not implemented #endif @@ -1473,7 +1415,9 @@ template<> struct __cxx_is_always_lock_free<char8_t> { enum { __value = 2 == ATO #endif template<> struct __cxx_is_always_lock_free<char16_t> { enum { __value = 2 == ATOMIC_CHAR16_T_LOCK_FREE }; }; template<> struct __cxx_is_always_lock_free<char32_t> { enum { __value = 2 == ATOMIC_CHAR32_T_LOCK_FREE }; }; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS template<> struct __cxx_is_always_lock_free<wchar_t> { enum { __value = 2 == ATOMIC_WCHAR_T_LOCK_FREE }; }; +#endif template<> struct __cxx_is_always_lock_free<short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; }; template<> struct __cxx_is_always_lock_free<unsigned short> { enum { __value = 2 == ATOMIC_SHORT_LOCK_FREE }; }; template<> struct __cxx_is_always_lock_free<int> { enum { __value = 2 == ATOMIC_INT_LOCK_FREE }; }; @@ -1496,11 +1440,8 @@ template <typename _Tp, typename _Base = __cxx_atomic_base_impl<_Tp> > #endif //_LIBCPP_ATOMIC_ONLY_USE_BUILTINS struct __cxx_atomic_impl : public _Base { - -#if _GNUC_VER >= 501 static_assert(is_trivially_copyable<_Tp>::value, - "std::atomic<Tp> requires that 'Tp' be a trivially copyable type"); -#endif + "std::atomic<T> requires that 'T' be a trivially copyable type"); _LIBCPP_INLINE_VISIBILITY __cxx_atomic_impl() _NOEXCEPT _LIBCPP_DEFAULT _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp value) _NOEXCEPT @@ -1515,6 +1456,16 @@ struct __cxx_atomic_impl : public _Base { using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; +#if defined(_LIBCPP_HAS_NO_THREADS) +# define _LIBCPP_HAS_NO_PLATFORM_WAIT +#endif + +// TODO: +// _LIBCPP_HAS_NO_PLATFORM_WAIT is currently a "dead" macro, in the sense that +// it is not tied anywhere into the build system or even documented. We should +// clean it up because it is technically never defined except when threads are +// disabled. We should clean it up in its own changeset in case we break "bad" +// users. #ifndef _LIBCPP_HAS_NO_PLATFORM_WAIT _LIBCPP_AVAILABILITY_SYNC _LIBCPP_EXPORTED_FROM_ABI void __cxx_atomic_notify_one(void const volatile*); @@ -1566,7 +1517,12 @@ _LIBCPP_INLINE_VISIBILITY void __cxx_atomic_notify_one(__cxx_atomic_impl<_Tp> co template <class _Atp, class _Fn> _LIBCPP_INLINE_VISIBILITY bool __cxx_atomic_wait(_Atp*, _Fn && __test_fn) { - return __libcpp_thread_poll_with_backoff(__test_fn, __libcpp_timed_backoff_policy()); +#if defined(_LIBCPP_HAS_NO_THREADS) + using _Policy = __spinning_backoff_policy; +#else + using _Policy = __libcpp_timed_backoff_policy; +#endif + return __libcpp_thread_poll_with_backoff(__test_fn, _Policy()); } #endif // _LIBCPP_HAS_NO_PLATFORM_WAIT @@ -1847,19 +1803,32 @@ struct atomic<_Tp*> {__base::store(__d); return __d;} _LIBCPP_INLINE_VISIBILITY - _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) - volatile _NOEXCEPT - {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} + _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed"); + return __cxx_atomic_fetch_add(&this->__a_, __op, __m); + } + _LIBCPP_INLINE_VISIBILITY - _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __cxx_atomic_fetch_add(&this->__a_, __op, __m);} + _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed"); + return __cxx_atomic_fetch_add(&this->__a_, __op, __m); + } + _LIBCPP_INLINE_VISIBILITY - _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) - volatile _NOEXCEPT - {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} + _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed"); + return __cxx_atomic_fetch_sub(&this->__a_, __op, __m); + } + _LIBCPP_INLINE_VISIBILITY - _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT - {return __cxx_atomic_fetch_sub(&this->__a_, __op, __m);} + _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT { + // __atomic_fetch_add accepts function pointers, guard against them. + static_assert(!is_function<typename remove_pointer<_Tp>::type>::value, "Pointer to function isn't allowed"); + return __cxx_atomic_fetch_sub(&this->__a_, __op, __m); + } _LIBCPP_INLINE_VISIBILITY _Tp* operator++(int) volatile _NOEXCEPT {return fetch_add(1);} @@ -2195,11 +2164,7 @@ void atomic_notify_all(atomic<_Tp>* __o) _NOEXCEPT template <class _Tp> _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value, - _Tp ->::type +_Tp atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { return __o->fetch_add(__op); @@ -2207,70 +2172,24 @@ atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_typ template <class _Tp> _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value, - _Tp ->::type +_Tp atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { return __o->fetch_add(__op); } -template <class _Tp> -_LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_add(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_add(__op); -} - -template <class _Tp> -_LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_add(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_add(__op); -} - // atomic_fetch_add_explicit template <class _Tp> _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value, - _Tp ->::type -atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT +_Tp atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { return __o->fetch_add(__op, __m); } template <class _Tp> _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value, - _Tp ->::type -atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_add(__op, __m); -} - -template <class _Tp> -_LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_add(__op, __m); -} - -template <class _Tp> -_LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_add_explicit(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT +_Tp atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { return __o->fetch_add(__op, __m); } @@ -2279,40 +2198,14 @@ atomic_fetch_add_explicit(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_t template <class _Tp> _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value, - _Tp ->::type -atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT +_Tp atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { return __o->fetch_sub(__op); } template <class _Tp> _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value, - _Tp ->::type -atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_sub(__op); -} - -template <class _Tp> -_LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_sub(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT -{ - return __o->fetch_sub(__op); -} - -template <class _Tp> -_LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_sub(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) _NOEXCEPT +_Tp atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT { return __o->fetch_sub(__op); } @@ -2321,40 +2214,14 @@ atomic_fetch_sub(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op) template <class _Tp> _LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value, - _Tp ->::type -atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_sub(__op, __m); -} - -template <class _Tp> -_LIBCPP_INLINE_VISIBILITY -typename enable_if -< - is_integral<_Tp>::value && !is_same<_Tp, bool>::value && !is_const<_Tp>::value, - _Tp ->::type -atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT -{ - return __o->fetch_sub(__op, __m); -} - -template <class _Tp> -_LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT +_Tp atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { return __o->fetch_sub(__op, __m); } template <class _Tp> _LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_sub_explicit(atomic<_Tp*>* __o, typename atomic<_Tp*>::difference_type __op, memory_order __m) _NOEXCEPT +_Tp atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT { return __o->fetch_sub(__op, __m); } @@ -2764,7 +2631,9 @@ typedef atomic<char8_t> atomic_char8_t; #endif typedef atomic<char16_t> atomic_char16_t; typedef atomic<char32_t> atomic_char32_t; +#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS typedef atomic<wchar_t> atomic_wchar_t; +#endif typedef atomic<int_least8_t> atomic_int_least8_t; typedef atomic<uint_least8_t> atomic_uint_least8_t; |
