Update atomic feature macros, synopsis, signatures to match C++20. Improve test coverage for non-lock-free atomics.

This commit is contained in:
Olivier Giroux 2020-09-09 10:00:09 -07:00
parent 4b15fc9ddb
commit fc4bff0cd3
15 changed files with 857 additions and 186 deletions

View File

@ -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*

View File

@ -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);
}

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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; }

View File

@ -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>()();
}
};

View File

@ -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>>();
*/

View File

@ -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"

View File

@ -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; }

View File

@ -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; }

View File

@ -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

View File

@ -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"

View File

@ -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++) {

View File

@ -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():