forked from OSchip/llvm-project
Update atomic feature macros, synopsis, signatures to match C++20. Improve test coverage for non-lock-free atomics.
This commit is contained in:
parent
4b15fc9ddb
commit
fc4bff0cd3
|
@ -170,8 +170,20 @@ Status
|
|||
-------------------------------------------------------------------
|
||||
``__cpp_lib_array_constexpr`` ``201811L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_atomic_flag_test`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_atomic_float`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_atomic_lock_free_type_aliases`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_atomic_ref`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_atomic_shared_ptr`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_atomic_value_initialization`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_atomic_wait`` ``201907L``
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_bind_front`` *unimplemented*
|
||||
------------------------------------------------- -----------------
|
||||
``__cpp_lib_bit_cast`` *unimplemented*
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
namespace std
|
||||
{
|
||||
|
||||
// feature test macro
|
||||
// feature test macro [version.syn]
|
||||
|
||||
#define __cpp_lib_atomic_is_always_lock_free // as specified by SG10
|
||||
#define __cpp_lib_atomic_is_always_lock_free
|
||||
#define __cpp_lib_atomic_flag_test
|
||||
#define __cpp_lib_atomic_lock_free_type_aliases
|
||||
#define __cpp_lib_atomic_wait
|
||||
|
||||
// order and consistency
|
||||
|
||||
|
@ -108,6 +111,7 @@ template <>
|
|||
struct atomic<integral>
|
||||
{
|
||||
using value_type = integral;
|
||||
using difference_type = value_type;
|
||||
|
||||
static constexpr bool is_always_lock_free;
|
||||
bool is_lock_free() const volatile noexcept;
|
||||
|
@ -190,6 +194,7 @@ template <class T>
|
|||
struct atomic<T*>
|
||||
{
|
||||
using value_type = T*;
|
||||
using difference_type = ptrdiff_t;
|
||||
|
||||
static constexpr bool is_always_lock_free;
|
||||
bool is_lock_free() const volatile noexcept;
|
||||
|
@ -1245,10 +1250,10 @@ template <typename _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool __cxx_atomic_compare_exchange_strong(volatile __cxx_atomic_lock_impl<_Tp>* __a,
|
||||
_Tp* __expected, _Tp __value, memory_order, memory_order) {
|
||||
__a->__lock();
|
||||
_Tp __temp;
|
||||
__a->__lock();
|
||||
__cxx_atomic_assign_volatile(__temp, __a->__a_value);
|
||||
bool __ret = __temp == *__expected;
|
||||
bool __ret = (memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
|
||||
if(__ret)
|
||||
__cxx_atomic_assign_volatile(__a->__a_value, __value);
|
||||
else
|
||||
|
@ -1261,11 +1266,11 @@ _LIBCPP_INLINE_VISIBILITY
|
|||
bool __cxx_atomic_compare_exchange_strong(__cxx_atomic_lock_impl<_Tp>* __a,
|
||||
_Tp* __expected, _Tp __value, memory_order, memory_order) {
|
||||
__a->__lock();
|
||||
bool __ret = __a->__a_value == *__expected;
|
||||
bool __ret = (memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
|
||||
if(__ret)
|
||||
__a->__a_value = __value;
|
||||
memcpy(&__a->__a_value, &__value, sizeof(_Tp));
|
||||
else
|
||||
*__expected = __a->__a_value;
|
||||
memcpy(__expected, &__a->__a_value, sizeof(_Tp));
|
||||
__a->__unlock();
|
||||
return __ret;
|
||||
}
|
||||
|
@ -1274,10 +1279,10 @@ template <typename _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool __cxx_atomic_compare_exchange_weak(volatile __cxx_atomic_lock_impl<_Tp>* __a,
|
||||
_Tp* __expected, _Tp __value, memory_order, memory_order) {
|
||||
__a->__lock();
|
||||
_Tp __temp;
|
||||
__a->__lock();
|
||||
__cxx_atomic_assign_volatile(__temp, __a->__a_value);
|
||||
bool __ret = __temp == *__expected;
|
||||
bool __ret = (memcmp(&__temp, __expected, sizeof(_Tp)) == 0);
|
||||
if(__ret)
|
||||
__cxx_atomic_assign_volatile(__a->__a_value, __value);
|
||||
else
|
||||
|
@ -1290,11 +1295,11 @@ _LIBCPP_INLINE_VISIBILITY
|
|||
bool __cxx_atomic_compare_exchange_weak(__cxx_atomic_lock_impl<_Tp>* __a,
|
||||
_Tp* __expected, _Tp __value, memory_order, memory_order) {
|
||||
__a->__lock();
|
||||
bool __ret = __a->__a_value == *__expected;
|
||||
bool __ret = (memcmp(&__a->__a_value, __expected, sizeof(_Tp)) == 0);
|
||||
if(__ret)
|
||||
__a->__a_value = __value;
|
||||
memcpy(&__a->__a_value, &__value, sizeof(_Tp));
|
||||
else
|
||||
*__expected = __a->__a_value;
|
||||
memcpy(__expected, &__a->__a_value, sizeof(_Tp));
|
||||
__a->__unlock();
|
||||
return __ret;
|
||||
}
|
||||
|
@ -1775,6 +1780,7 @@ struct atomic
|
|||
{
|
||||
typedef __atomic_base<_Tp> __base;
|
||||
typedef _Tp value_type;
|
||||
typedef value_type difference_type;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
atomic() _NOEXCEPT _LIBCPP_DEFAULT
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
@ -1796,6 +1802,7 @@ struct atomic<_Tp*>
|
|||
{
|
||||
typedef __atomic_base<_Tp*> __base;
|
||||
typedef _Tp* value_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
atomic() _NOEXCEPT _LIBCPP_DEFAULT
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
@ -1872,7 +1879,7 @@ atomic_is_lock_free(const atomic<_Tp>* __o) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
||||
atomic_init(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
__cxx_atomic_init(&__o->__a_, __d);
|
||||
}
|
||||
|
@ -1880,7 +1887,7 @@ atomic_init(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
||||
atomic_init(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
__cxx_atomic_init(&__o->__a_, __d);
|
||||
}
|
||||
|
@ -1890,7 +1897,7 @@ atomic_init(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
||||
atomic_store(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
__o->store(__d);
|
||||
}
|
||||
|
@ -1898,7 +1905,7 @@ atomic_store(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
||||
atomic_store(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
__o->store(__d);
|
||||
}
|
||||
|
@ -1908,7 +1915,7 @@ atomic_store(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
|
||||
atomic_store_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
|
||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
|
||||
{
|
||||
__o->store(__d, __m);
|
||||
|
@ -1917,7 +1924,7 @@ atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOE
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
void
|
||||
atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
|
||||
atomic_store_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
|
||||
_LIBCPP_CHECK_STORE_MEMORY_ORDER(__m)
|
||||
{
|
||||
__o->store(__d, __m);
|
||||
|
@ -1966,7 +1973,7 @@ atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Tp
|
||||
atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
||||
atomic_exchange(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
return __o->exchange(__d);
|
||||
}
|
||||
|
@ -1974,7 +1981,7 @@ atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Tp
|
||||
atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
||||
atomic_exchange(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
return __o->exchange(__d);
|
||||
}
|
||||
|
@ -1984,7 +1991,7 @@ atomic_exchange(atomic<_Tp>* __o, _Tp __d) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Tp
|
||||
atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
|
||||
atomic_exchange_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->exchange(__d, __m);
|
||||
}
|
||||
|
@ -1992,7 +1999,7 @@ atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Tp
|
||||
atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
|
||||
atomic_exchange_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __d, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->exchange(__d, __m);
|
||||
}
|
||||
|
@ -2002,7 +2009,7 @@ atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
|
||||
atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
return __o->compare_exchange_weak(*__e, __d);
|
||||
}
|
||||
|
@ -2010,7 +2017,7 @@ atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEX
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
|
||||
atomic_compare_exchange_weak(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
return __o->compare_exchange_weak(*__e, __d);
|
||||
}
|
||||
|
@ -2020,7 +2027,7 @@ atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
|
||||
atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
return __o->compare_exchange_strong(*__e, __d);
|
||||
}
|
||||
|
@ -2028,7 +2035,7 @@ atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NO
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
|
||||
atomic_compare_exchange_strong(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d) _NOEXCEPT
|
||||
{
|
||||
return __o->compare_exchange_strong(*__e, __d);
|
||||
}
|
||||
|
@ -2038,8 +2045,8 @@ atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d) _NOEXCEPT
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
|
||||
_Tp __d,
|
||||
atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
|
||||
typename atomic<_Tp>::value_type __d,
|
||||
memory_order __s, memory_order __f) _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
|
||||
{
|
||||
|
@ -2049,7 +2056,7 @@ atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
|
||||
atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
|
||||
memory_order __s, memory_order __f) _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
|
||||
{
|
||||
|
@ -2062,7 +2069,7 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
|
||||
_Tp* __e, _Tp __d,
|
||||
typename atomic<_Tp>::value_type* __e, typename atomic<_Tp>::value_type __d,
|
||||
memory_order __s, memory_order __f) _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
|
||||
{
|
||||
|
@ -2072,8 +2079,8 @@ atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
|
|||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
bool
|
||||
atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
|
||||
_Tp __d,
|
||||
atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type* __e,
|
||||
typename atomic<_Tp>::value_type __d,
|
||||
memory_order __s, memory_order __f) _NOEXCEPT
|
||||
_LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER(__s, __f)
|
||||
{
|
||||
|
@ -2156,10 +2163,10 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
is_pointer<_Tp>::value || (is_integral<_Tp>::value && !is_same<_Tp, bool>::value),
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
atomic_fetch_add(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_add(__op);
|
||||
}
|
||||
|
@ -2168,26 +2175,10 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
is_pointer<_Tp>::value || (is_integral<_Tp>::value && !is_same<_Tp, bool>::value),
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_add(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_add(__op);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Tp*
|
||||
atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_add(__op);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Tp*
|
||||
atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
|
||||
atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_add(__op);
|
||||
}
|
||||
|
@ -2198,10 +2189,10 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
is_pointer<_Tp>::value || (is_integral<_Tp>::value && !is_same<_Tp, bool>::value),
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_add(__op, __m);
|
||||
}
|
||||
|
@ -2210,27 +2201,10 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
is_pointer<_Tp>::value || (is_integral<_Tp>::value && !is_same<_Tp, bool>::value),
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __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, ptrdiff_t __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, ptrdiff_t __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_add(__op, __m);
|
||||
}
|
||||
|
@ -2241,10 +2215,10 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
is_pointer<_Tp>::value || (is_integral<_Tp>::value && !is_same<_Tp, bool>::value),
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
atomic_fetch_sub(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_sub(__op);
|
||||
}
|
||||
|
@ -2253,26 +2227,10 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
is_pointer<_Tp>::value || (is_integral<_Tp>::value && !is_same<_Tp, bool>::value),
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_sub(__op);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Tp*
|
||||
atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_sub(__op);
|
||||
}
|
||||
|
||||
template <class _Tp>
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
_Tp*
|
||||
atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT
|
||||
atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_sub(__op);
|
||||
}
|
||||
|
@ -2283,10 +2241,10 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
is_pointer<_Tp>::value || (is_integral<_Tp>::value && !is_same<_Tp, bool>::value),
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_sub(__op, __m);
|
||||
}
|
||||
|
@ -2295,27 +2253,10 @@ template <class _Tp>
|
|||
_LIBCPP_INLINE_VISIBILITY
|
||||
typename enable_if
|
||||
<
|
||||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
is_pointer<_Tp>::value || (is_integral<_Tp>::value && !is_same<_Tp, bool>::value),
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __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, ptrdiff_t __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, ptrdiff_t __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::difference_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_sub(__op, __m);
|
||||
}
|
||||
|
@ -2329,7 +2270,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
atomic_fetch_and(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_and(__op);
|
||||
}
|
||||
|
@ -2341,7 +2282,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_and(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
atomic_fetch_and(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_and(__op);
|
||||
}
|
||||
|
@ -2355,7 +2296,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_and(__op, __m);
|
||||
}
|
||||
|
@ -2367,7 +2308,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_and_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_and(__op, __m);
|
||||
}
|
||||
|
@ -2381,7 +2322,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
atomic_fetch_or(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_or(__op);
|
||||
}
|
||||
|
@ -2393,7 +2334,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_or(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
atomic_fetch_or(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_or(__op);
|
||||
}
|
||||
|
@ -2407,7 +2348,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_or(__op, __m);
|
||||
}
|
||||
|
@ -2419,7 +2360,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_or_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_or(__op, __m);
|
||||
}
|
||||
|
@ -2433,7 +2374,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
atomic_fetch_xor(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_xor(__op);
|
||||
}
|
||||
|
@ -2445,7 +2386,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op) _NOEXCEPT
|
||||
atomic_fetch_xor(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_xor(__op);
|
||||
}
|
||||
|
@ -2459,7 +2400,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_xor(__op, __m);
|
||||
}
|
||||
|
@ -2471,7 +2412,7 @@ typename enable_if
|
|||
is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
|
||||
_Tp
|
||||
>::type
|
||||
atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m) _NOEXCEPT
|
||||
atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __op, memory_order __m) _NOEXCEPT
|
||||
{
|
||||
return __o->fetch_xor(__op, __m);
|
||||
}
|
||||
|
|
|
@ -24,8 +24,14 @@ __cpp_lib_apply 201603L <tuple>
|
|||
__cpp_lib_array_constexpr 201811L <iterator> <array>
|
||||
201603L // C++17
|
||||
__cpp_lib_as_const 201510L <utility>
|
||||
__cpp_lib_atomic_flag_test 201907L <atomic>
|
||||
__cpp_lib_atomic_float 201711L <atomic>
|
||||
__cpp_lib_atomic_is_always_lock_free 201603L <atomic>
|
||||
__cpp_lib_atomic_lock_free_type_aliases 201907L <atomic>
|
||||
__cpp_lib_atomic_ref 201806L <atomic>
|
||||
__cpp_lib_atomic_shared_ptr 201711L <atomic>
|
||||
__cpp_lib_atomic_value_initialization 201911L <atomic> <memory>
|
||||
__cpp_lib_atomic_wait 201907L <atomic>
|
||||
__cpp_lib_bind_front 201811L <functional>
|
||||
__cpp_lib_bit_cast 201806L <bit>
|
||||
__cpp_lib_bool_constant 201505L <type_traits>
|
||||
|
@ -218,8 +224,26 @@ __cpp_lib_void_t 201411L <type_traits>
|
|||
# undef __cpp_lib_array_constexpr
|
||||
# define __cpp_lib_array_constexpr 201811L
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# define __cpp_lib_atomic_flag_test 201907L
|
||||
# endif
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
// # define __cpp_lib_atomic_float 201711L
|
||||
# endif
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# define __cpp_lib_atomic_lock_free_type_aliases 201907L
|
||||
# endif
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
// # define __cpp_lib_atomic_ref 201806L
|
||||
# endif
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
// # define __cpp_lib_atomic_shared_ptr 201711L
|
||||
# endif
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
// # define __cpp_lib_atomic_value_initialization 201911L
|
||||
# endif
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# define __cpp_lib_atomic_wait 201907L
|
||||
# endif
|
||||
// # define __cpp_lib_bind_front 201811L
|
||||
// # define __cpp_lib_bit_cast 201806L
|
||||
# if !defined(_LIBCPP_NO_HAS_CHAR8_T)
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// UNSUPPORTED: libcpp-has-no-threads
|
||||
|
||||
// <atomic>
|
||||
|
||||
// struct atomic_flag
|
||||
|
||||
// bool atomic_flag_test_and_set(volatile atomic_flag*);
|
||||
// bool atomic_flag_test_and_set(atomic_flag*);
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_and_set(&f) == 0);
|
||||
assert(f.test_and_set() == 1);
|
||||
}
|
||||
{
|
||||
volatile std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_and_set(&f) == 0);
|
||||
assert(f.test_and_set() == 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// UNSUPPORTED: libcpp-has-no-threads
|
||||
|
||||
// <atomic>
|
||||
|
||||
// struct atomic_flag
|
||||
|
||||
// bool atomic_flag_test_explicit(volatile atomic_flag*, memory_order);
|
||||
// bool atomic_flag_test_explicit(atomic_flag*, memory_order);
|
||||
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
{
|
||||
std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_relaxed) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_relaxed) == 1);
|
||||
}
|
||||
{
|
||||
std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_consume) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_consume) == 1);
|
||||
}
|
||||
{
|
||||
std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_acquire) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_acquire) == 1);
|
||||
}
|
||||
{
|
||||
std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_release) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_release) == 1);
|
||||
}
|
||||
{
|
||||
std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_acq_rel) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_acq_rel) == 1);
|
||||
}
|
||||
{
|
||||
std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_seq_cst) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_seq_cst) == 1);
|
||||
}
|
||||
{
|
||||
volatile std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_relaxed) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_relaxed) == 1);
|
||||
}
|
||||
{
|
||||
volatile std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_consume) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_consume) == 1);
|
||||
}
|
||||
{
|
||||
volatile std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_acquire) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_acquire) == 1);
|
||||
}
|
||||
{
|
||||
volatile std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_release) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_release) == 1);
|
||||
}
|
||||
{
|
||||
volatile std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_acq_rel) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_acq_rel) == 1);
|
||||
}
|
||||
{
|
||||
volatile std::atomic_flag f;
|
||||
f.clear();
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_seq_cst) == 0);
|
||||
assert(f.test_and_set() == 0);
|
||||
assert(atomic_flag_test_explicit(&f, std::memory_order_seq_cst) == 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -134,6 +134,11 @@ void run()
|
|||
checkLongLongTypes();
|
||||
static_assert(std::atomic<void*>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE), "");
|
||||
static_assert(std::atomic<std::nullptr_t>::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE), "");
|
||||
|
||||
#if TEST_STD_VER >= 20
|
||||
static_assert(std::atomic<std::atomic_signed_lock_free>::is_always_lock_free, "");
|
||||
static_assert(std::atomic<std::atomic_unsigned_lock_free>::is_always_lock_free, "");
|
||||
#endif
|
||||
}
|
||||
|
||||
int main(int, char**) { run(); return 0; }
|
||||
|
|
|
@ -23,6 +23,37 @@ struct UserAtomicType
|
|||
{ return x.i == y.i; }
|
||||
};
|
||||
|
||||
struct WeirdUserAtomicType
|
||||
{
|
||||
char i, j, k; /* the 3 chars of doom */
|
||||
|
||||
explicit WeirdUserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {}
|
||||
|
||||
friend bool operator==(const WeirdUserAtomicType& x, const WeirdUserAtomicType& y)
|
||||
{ return x.i == y.i; }
|
||||
};
|
||||
|
||||
struct PaddedUserAtomicType
|
||||
{
|
||||
char i; int j; /* probably lock-free? */
|
||||
|
||||
explicit PaddedUserAtomicType(int d = 0) TEST_NOEXCEPT : i(d) {}
|
||||
|
||||
friend bool operator==(const PaddedUserAtomicType& x, const PaddedUserAtomicType& y)
|
||||
{ return x.i == y.i; }
|
||||
};
|
||||
|
||||
struct LargeUserAtomicType
|
||||
{
|
||||
int i, j[127]; /* decidedly not lock-free */
|
||||
|
||||
LargeUserAtomicType(int d = 0) TEST_NOEXCEPT : i(d)
|
||||
{}
|
||||
|
||||
friend bool operator==(const LargeUserAtomicType& x, const LargeUserAtomicType& y)
|
||||
{ return x.i == y.i; }
|
||||
};
|
||||
|
||||
template < template <class TestArg> class TestFunctor >
|
||||
struct TestEachIntegralType {
|
||||
void operator()() const {
|
||||
|
@ -58,8 +89,19 @@ struct TestEachAtomicType {
|
|||
void operator()() const {
|
||||
TestEachIntegralType<TestFunctor>()();
|
||||
TestFunctor<UserAtomicType>()();
|
||||
TestFunctor<PaddedUserAtomicType>()();
|
||||
#ifndef __APPLE__
|
||||
/*
|
||||
These aren't going to be lock-free,
|
||||
so some libatomic.a is necessary.
|
||||
*/
|
||||
TestFunctor<WeirdUserAtomicType>()();
|
||||
TestFunctor<LargeUserAtomicType>()();
|
||||
#endif
|
||||
TestFunctor<int*>()();
|
||||
TestFunctor<const int*>()();
|
||||
TestFunctor<float>()();
|
||||
TestFunctor<double>()();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -30,15 +30,43 @@
|
|||
|
||||
#include "test_macros.h"
|
||||
|
||||
template <class A>
|
||||
void
|
||||
test_atomic()
|
||||
template <class A, bool Integral>
|
||||
struct test_atomic
|
||||
{
|
||||
A a; (void)a;
|
||||
test_atomic()
|
||||
{
|
||||
A a; (void)a;
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert((std::is_same<typename A::value_type, decltype(a.load())>::value), "");
|
||||
static_assert((std::is_same_v<typename A::value_type, decltype(a.load())>), "");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
struct test_atomic<A, true>
|
||||
{
|
||||
test_atomic()
|
||||
{
|
||||
A a; (void)a;
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert((std::is_same_v<typename A::value_type, decltype(a.load())>), "");
|
||||
static_assert((std::is_same_v<typename A::value_type, typename A::difference_type>), "");
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <class A>
|
||||
struct test_atomic<A*, false>
|
||||
{
|
||||
test_atomic()
|
||||
{
|
||||
A a; (void)a;
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert((std::is_same_v<typename A::value_type, decltype(a.load())>), "");
|
||||
static_assert((std::is_same_v<typename A::difference_type, ptrdiff_t>), "");
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void
|
||||
|
@ -46,15 +74,30 @@ test()
|
|||
{
|
||||
using A = std::atomic<T>;
|
||||
#if TEST_STD_VER >= 17
|
||||
static_assert((std::is_same<typename A::value_type, T>::value), "");
|
||||
static_assert((std::is_same_v<typename A::value_type, T>), "");
|
||||
#endif
|
||||
test_atomic<A>();
|
||||
test_atomic<A, std::is_integral<T>::value && !std::is_same<T, bool>::value>();
|
||||
}
|
||||
|
||||
struct TriviallyCopyable {
|
||||
int i_;
|
||||
};
|
||||
|
||||
struct WeirdTriviallyCopyable
|
||||
{
|
||||
char i, j, k; /* the 3 chars of doom */
|
||||
};
|
||||
|
||||
struct PaddedTriviallyCopyable
|
||||
{
|
||||
char i; int j; /* probably lock-free? */
|
||||
};
|
||||
|
||||
struct LargeTriviallyCopyable
|
||||
{
|
||||
int i, j[127]; /* decidedly not lock-free */
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
test<bool> ();
|
||||
|
@ -111,13 +154,23 @@ int main(int, char**)
|
|||
test<uintmax_t> ();
|
||||
|
||||
test<TriviallyCopyable>();
|
||||
test<PaddedTriviallyCopyable>();
|
||||
#ifndef __APPLE__
|
||||
/*
|
||||
These aren't going to be lock-free,
|
||||
so some libatomic.a is necessary.
|
||||
*/
|
||||
test<WeirdTriviallyCopyable>();
|
||||
test<LargeTriviallyCopyable>();
|
||||
#endif
|
||||
|
||||
test<std::thread::id>();
|
||||
test<std::chrono::nanoseconds>();
|
||||
test<float>();
|
||||
|
||||
#if TEST_STD_VER >= 20
|
||||
test_atomic<std::atomic_signed_lock_free>();
|
||||
test_atomic<std::atomic_unsigned_lock_free>();
|
||||
test<std::atomic_signed_lock_free>();
|
||||
test<std::atomic_unsigned_lock_free>();
|
||||
/*
|
||||
test<std::shared_ptr<int>>();
|
||||
*/
|
||||
|
|
|
@ -15,10 +15,16 @@
|
|||
|
||||
// Test the feature test macros defined by <atomic>
|
||||
|
||||
/* Constant Value
|
||||
__cpp_lib_atomic_is_always_lock_free 201603L [C++17]
|
||||
__cpp_lib_atomic_ref 201806L [C++2a]
|
||||
__cpp_lib_char8_t 201811L [C++2a]
|
||||
/* Constant Value
|
||||
__cpp_lib_atomic_flag_test 201907L [C++2a]
|
||||
__cpp_lib_atomic_float 201711L [C++2a]
|
||||
__cpp_lib_atomic_is_always_lock_free 201603L [C++17]
|
||||
__cpp_lib_atomic_lock_free_type_aliases 201907L [C++2a]
|
||||
__cpp_lib_atomic_ref 201806L [C++2a]
|
||||
__cpp_lib_atomic_shared_ptr 201711L [C++2a]
|
||||
__cpp_lib_atomic_value_initialization 201911L [C++2a]
|
||||
__cpp_lib_atomic_wait 201907L [C++2a]
|
||||
__cpp_lib_char8_t 201811L [C++2a]
|
||||
*/
|
||||
|
||||
#include <atomic>
|
||||
|
@ -26,34 +32,90 @@
|
|||
|
||||
#if TEST_STD_VER < 14
|
||||
|
||||
# ifdef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_is_always_lock_free
|
||||
# error "__cpp_lib_atomic_is_always_lock_free should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_ref
|
||||
# error "__cpp_lib_atomic_ref should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_char8_t
|
||||
# error "__cpp_lib_char8_t should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
#elif TEST_STD_VER == 14
|
||||
|
||||
# ifdef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_is_always_lock_free
|
||||
# error "__cpp_lib_atomic_is_always_lock_free should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_ref
|
||||
# error "__cpp_lib_atomic_ref should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_char8_t
|
||||
# error "__cpp_lib_char8_t should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
#elif TEST_STD_VER == 17
|
||||
|
||||
# ifdef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_is_always_lock_free
|
||||
# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++17"
|
||||
|
@ -67,16 +129,58 @@
|
|||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_ref
|
||||
# error "__cpp_lib_atomic_ref should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_char8_t
|
||||
# error "__cpp_lib_char8_t should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
#elif TEST_STD_VER > 17
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_flag_test != 201907L
|
||||
# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++2a"
|
||||
# endif
|
||||
# else
|
||||
# ifdef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_float != 201711L
|
||||
# error "__cpp_lib_atomic_float should have the value 201711L in c++2a"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_is_always_lock_free
|
||||
# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++2a"
|
||||
|
@ -90,6 +194,19 @@
|
|||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_lock_free_type_aliases != 201907L
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++2a"
|
||||
# endif
|
||||
# else
|
||||
# ifdef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_atomic_ref
|
||||
# error "__cpp_lib_atomic_ref should be defined in c++2a"
|
||||
|
@ -103,6 +220,45 @@
|
|||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_shared_ptr != 201711L
|
||||
# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++2a"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_value_initialization != 201911L
|
||||
# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++2a"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_wait != 201907L
|
||||
# error "__cpp_lib_atomic_wait should have the value 201907L in c++2a"
|
||||
# endif
|
||||
# else
|
||||
# ifdef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(__cpp_char8_t)
|
||||
# ifndef __cpp_lib_char8_t
|
||||
# error "__cpp_lib_char8_t should be defined in c++2a"
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
|
@ -7,29 +6,53 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// <concepts> feature macros
|
||||
// WARNING: This test was generated by generate_feature_test_macro_components.py
|
||||
// and should not be edited manually.
|
||||
|
||||
/* Constant Value
|
||||
__cpp_lib_concepts 201806L
|
||||
// <concepts>
|
||||
|
||||
// Test the feature test macros defined by <concepts>
|
||||
|
||||
/* Constant Value
|
||||
__cpp_lib_concepts 201806L [C++2a]
|
||||
*/
|
||||
|
||||
// XFAIL
|
||||
// #include <concepts>
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
// ensure that the macros that are supposed to be defined in <concepts> are defined.
|
||||
#if TEST_STD_VER < 14
|
||||
|
||||
/*
|
||||
#if !defined(__cpp_lib_fooby)
|
||||
# error "__cpp_lib_fooby is not defined"
|
||||
#elif __cpp_lib_fooby < 201606L
|
||||
# error "__cpp_lib_fooby has an invalid value"
|
||||
#endif
|
||||
*/
|
||||
# ifdef __cpp_lib_concepts
|
||||
# error "__cpp_lib_concepts should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#elif TEST_STD_VER == 14
|
||||
|
||||
# ifdef __cpp_lib_concepts
|
||||
# error "__cpp_lib_concepts should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
#elif TEST_STD_VER == 17
|
||||
|
||||
# ifdef __cpp_lib_concepts
|
||||
# error "__cpp_lib_concepts should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
#elif TEST_STD_VER > 17
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_concepts
|
||||
# error "__cpp_lib_concepts should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_concepts != 201806L
|
||||
# error "__cpp_lib_concepts should have the value 201806L in c++2a"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_concepts
|
||||
# error "__cpp_lib_concepts should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif // TEST_STD_VER > 17
|
||||
|
||||
int main(int, char**) { return 0; }
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
|
@ -7,29 +6,62 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// <execution> feature macros
|
||||
// WARNING: This test was generated by generate_feature_test_macro_components.py
|
||||
// and should not be edited manually.
|
||||
|
||||
/* Constant Value
|
||||
__cpp_lib_execution 201603L
|
||||
// <execution>
|
||||
|
||||
// Test the feature test macros defined by <execution>
|
||||
|
||||
/* Constant Value
|
||||
__cpp_lib_execution 201603L [C++17]
|
||||
*/
|
||||
|
||||
// XFAIL
|
||||
// #include <execution>
|
||||
#include <cassert>
|
||||
#include <execution>
|
||||
#include "test_macros.h"
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
// ensure that the macros that are supposed to be defined in <execution> are defined.
|
||||
#if TEST_STD_VER < 14
|
||||
|
||||
/*
|
||||
#if !defined(__cpp_lib_fooby)
|
||||
# error "__cpp_lib_fooby is not defined"
|
||||
#elif __cpp_lib_fooby < 201606L
|
||||
# error "__cpp_lib_fooby has an invalid value"
|
||||
#endif
|
||||
*/
|
||||
# ifdef __cpp_lib_execution
|
||||
# error "__cpp_lib_execution should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#elif TEST_STD_VER == 14
|
||||
|
||||
# ifdef __cpp_lib_execution
|
||||
# error "__cpp_lib_execution should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
#elif TEST_STD_VER == 17
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_execution
|
||||
# error "__cpp_lib_execution should be defined in c++17"
|
||||
# endif
|
||||
# if __cpp_lib_execution != 201603L
|
||||
# error "__cpp_lib_execution should have the value 201603L in c++17"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_execution
|
||||
# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#elif TEST_STD_VER > 17
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_execution
|
||||
# error "__cpp_lib_execution should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_execution != 201603L
|
||||
# error "__cpp_lib_execution should have the value 201603L in c++2a"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_execution
|
||||
# error "__cpp_lib_execution should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif // TEST_STD_VER > 17
|
||||
|
||||
int main(int, char**) { return 0; }
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
/* Constant Value
|
||||
__cpp_lib_addressof_constexpr 201603L [C++17]
|
||||
__cpp_lib_allocator_traits_is_always_equal 201411L [C++17]
|
||||
__cpp_lib_atomic_value_initialization 201911L [C++2a]
|
||||
__cpp_lib_enable_shared_from_this 201603L [C++17]
|
||||
__cpp_lib_make_unique 201304L [C++14]
|
||||
__cpp_lib_ranges 201811L [C++2a]
|
||||
|
@ -37,6 +38,10 @@
|
|||
# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_enable_shared_from_this
|
||||
# error "__cpp_lib_enable_shared_from_this should not be defined before c++17"
|
||||
# endif
|
||||
|
@ -71,6 +76,10 @@
|
|||
# error "__cpp_lib_allocator_traits_is_always_equal should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_enable_shared_from_this
|
||||
# error "__cpp_lib_enable_shared_from_this should not be defined before c++17"
|
||||
# endif
|
||||
|
@ -120,6 +129,10 @@
|
|||
# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifndef __cpp_lib_enable_shared_from_this
|
||||
# error "__cpp_lib_enable_shared_from_this should be defined in c++17"
|
||||
# endif
|
||||
|
@ -187,6 +200,19 @@
|
|||
# error "__cpp_lib_allocator_traits_is_always_equal should have the value 201411L in c++2a"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_value_initialization != 201911L
|
||||
# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++2a"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# ifndef __cpp_lib_enable_shared_from_this
|
||||
# error "__cpp_lib_enable_shared_from_this should be defined in c++2a"
|
||||
# endif
|
||||
|
|
|
@ -21,8 +21,14 @@
|
|||
__cpp_lib_array_constexpr 201603L [C++17]
|
||||
201811L [C++2a]
|
||||
__cpp_lib_as_const 201510L [C++17]
|
||||
__cpp_lib_atomic_flag_test 201907L [C++2a]
|
||||
__cpp_lib_atomic_float 201711L [C++2a]
|
||||
__cpp_lib_atomic_is_always_lock_free 201603L [C++17]
|
||||
__cpp_lib_atomic_lock_free_type_aliases 201907L [C++2a]
|
||||
__cpp_lib_atomic_ref 201806L [C++2a]
|
||||
__cpp_lib_atomic_shared_ptr 201711L [C++2a]
|
||||
__cpp_lib_atomic_value_initialization 201911L [C++2a]
|
||||
__cpp_lib_atomic_wait 201907L [C++2a]
|
||||
__cpp_lib_bind_front 201811L [C++2a]
|
||||
__cpp_lib_bit_cast 201806L [C++2a]
|
||||
__cpp_lib_bool_constant 201505L [C++17]
|
||||
|
@ -135,14 +141,38 @@
|
|||
# error "__cpp_lib_as_const should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_is_always_lock_free
|
||||
# error "__cpp_lib_atomic_is_always_lock_free should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_ref
|
||||
# error "__cpp_lib_atomic_ref should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_bind_front
|
||||
# error "__cpp_lib_bind_front should not be defined before c++2a"
|
||||
# endif
|
||||
|
@ -489,14 +519,38 @@
|
|||
# error "__cpp_lib_as_const should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_is_always_lock_free
|
||||
# error "__cpp_lib_atomic_is_always_lock_free should not be defined before c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_ref
|
||||
# error "__cpp_lib_atomic_ref should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_bind_front
|
||||
# error "__cpp_lib_bind_front should not be defined before c++2a"
|
||||
# endif
|
||||
|
@ -933,6 +987,14 @@
|
|||
# error "__cpp_lib_as_const should have the value 201510L in c++17"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_is_always_lock_free
|
||||
# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++17"
|
||||
|
@ -946,10 +1008,26 @@
|
|||
# endif
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_ref
|
||||
# error "__cpp_lib_atomic_ref should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should not be defined before c++2a"
|
||||
# endif
|
||||
|
||||
# ifdef __cpp_lib_bind_front
|
||||
# error "__cpp_lib_bind_front should not be defined before c++2a"
|
||||
# endif
|
||||
|
@ -1575,6 +1653,32 @@
|
|||
# error "__cpp_lib_as_const should have the value 201510L in c++2a"
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_flag_test != 201907L
|
||||
# error "__cpp_lib_atomic_flag_test should have the value 201907L in c++2a"
|
||||
# endif
|
||||
# else
|
||||
# ifdef __cpp_lib_atomic_flag_test
|
||||
# error "__cpp_lib_atomic_flag_test should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_float != 201711L
|
||||
# error "__cpp_lib_atomic_float should have the value 201711L in c++2a"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_atomic_float
|
||||
# error "__cpp_lib_atomic_float should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_is_always_lock_free
|
||||
# error "__cpp_lib_atomic_is_always_lock_free should be defined in c++2a"
|
||||
|
@ -1588,6 +1692,19 @@
|
|||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_lock_free_type_aliases != 201907L
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should have the value 201907L in c++2a"
|
||||
# endif
|
||||
# else
|
||||
# ifdef __cpp_lib_atomic_lock_free_type_aliases
|
||||
# error "__cpp_lib_atomic_lock_free_type_aliases should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_atomic_ref
|
||||
# error "__cpp_lib_atomic_ref should be defined in c++2a"
|
||||
|
@ -1601,6 +1718,45 @@
|
|||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_shared_ptr != 201711L
|
||||
# error "__cpp_lib_atomic_shared_ptr should have the value 201711L in c++2a"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_atomic_shared_ptr
|
||||
# error "__cpp_lib_atomic_shared_ptr should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_value_initialization != 201911L
|
||||
# error "__cpp_lib_atomic_value_initialization should have the value 201911L in c++2a"
|
||||
# endif
|
||||
# else // _LIBCPP_VERSION
|
||||
# ifdef __cpp_lib_atomic_value_initialization
|
||||
# error "__cpp_lib_atomic_value_initialization should not be defined because it is unimplemented in libc++!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_HAS_NO_THREADS)
|
||||
# ifndef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should be defined in c++2a"
|
||||
# endif
|
||||
# if __cpp_lib_atomic_wait != 201907L
|
||||
# error "__cpp_lib_atomic_wait should have the value 201907L in c++2a"
|
||||
# endif
|
||||
# else
|
||||
# ifdef __cpp_lib_atomic_wait
|
||||
# error "__cpp_lib_atomic_wait should not be defined when !defined(_LIBCPP_HAS_NO_THREADS) is not defined!"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if !defined(_LIBCPP_VERSION)
|
||||
# ifndef __cpp_lib_bind_front
|
||||
# error "__cpp_lib_bind_front should be defined in c++2a"
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
#include <atomic>
|
||||
|
||||
template <class A, class T>
|
||||
bool cmpxchg_weak_loop(A& atomic, T& expected, T desired) {
|
||||
template <class A>
|
||||
bool cmpxchg_weak_loop(A& atomic, typename A::value_type& expected, typename A::value_type desired) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (atomic.compare_exchange_weak(expected, desired) == true) {
|
||||
return true;
|
||||
|
@ -19,8 +19,8 @@ bool cmpxchg_weak_loop(A& atomic, T& expected, T desired) {
|
|||
return false;
|
||||
}
|
||||
|
||||
template <class A, class T>
|
||||
bool cmpxchg_weak_loop(A& atomic, T& expected, T desired,
|
||||
template <class A>
|
||||
bool cmpxchg_weak_loop(A& atomic, typename A::value_type& expected, typename A::value_type desired,
|
||||
std::memory_order success,
|
||||
std::memory_order failure) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
@ -33,8 +33,8 @@ bool cmpxchg_weak_loop(A& atomic, T& expected, T desired,
|
|||
return false;
|
||||
}
|
||||
|
||||
template <class A, class T>
|
||||
bool c_cmpxchg_weak_loop(A* atomic, T* expected, T desired) {
|
||||
template <class A>
|
||||
bool c_cmpxchg_weak_loop(A* atomic, typename A::value_type* expected, typename A::value_type desired) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
if (std::atomic_compare_exchange_weak(atomic, expected, desired) == true) {
|
||||
return true;
|
||||
|
@ -44,8 +44,8 @@ bool c_cmpxchg_weak_loop(A* atomic, T* expected, T desired) {
|
|||
return false;
|
||||
}
|
||||
|
||||
template <class A, class T>
|
||||
bool c_cmpxchg_weak_loop(A* atomic, T* expected, T desired,
|
||||
template <class A>
|
||||
bool c_cmpxchg_weak_loop(A* atomic, typename A::value_type* expected, typename A::value_type desired,
|
||||
std::memory_order success,
|
||||
std::memory_order failure) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
|
|
@ -613,6 +613,57 @@ feature_test_macros = sorted([ add_version_header(x) for x in [
|
|||
},
|
||||
"headers": ["utility"],
|
||||
},
|
||||
{"name": "__cpp_lib_atomic_flag_test",
|
||||
"values": {
|
||||
"c++2a": int(201907),
|
||||
},
|
||||
"headers": ["atomic"],
|
||||
"depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
"internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
},
|
||||
{"name": "__cpp_lib_atomic_lock_free_type_aliases",
|
||||
"values": {
|
||||
"c++2a": int(201907),
|
||||
},
|
||||
"headers": ["atomic"],
|
||||
"depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
"internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
},
|
||||
{"name": "__cpp_lib_atomic_wait",
|
||||
"values": {
|
||||
"c++2a": int(201907),
|
||||
},
|
||||
"headers": ["atomic"],
|
||||
"depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
"internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
},
|
||||
{"name": "__cpp_lib_atomic_float",
|
||||
"values": {
|
||||
"c++2a": int(201711),
|
||||
},
|
||||
"headers": ["atomic"],
|
||||
"unimplemented": True,
|
||||
"depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
"internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
},
|
||||
{"name": "__cpp_lib_atomic_shared_ptr",
|
||||
"values": {
|
||||
"c++2a": int(201711),
|
||||
},
|
||||
"headers": ["atomic"],
|
||||
"unimplemented": True,
|
||||
"depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
"internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
},
|
||||
{"name": "__cpp_lib_atomic_value_initialization",
|
||||
"values": {
|
||||
"c++2a": int(201911),
|
||||
},
|
||||
"headers": ["atomic", "memory"],
|
||||
"unimplemented": True,
|
||||
"depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
"internal_depends": "!defined(_LIBCPP_HAS_NO_THREADS)",
|
||||
},
|
||||
]], key=lambda tc: tc["name"])
|
||||
|
||||
def get_std_dialects():
|
||||
|
|
Loading…
Reference in New Issue