diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst --- a/libcxx/docs/FeatureTestMacroTable.rst +++ b/libcxx/docs/FeatureTestMacroTable.rst @@ -170,8 +170,20 @@ ------------------------------------------------------------------- ``__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* diff --git a/libcxx/include/atomic b/libcxx/include/atomic --- a/libcxx/include/atomic +++ b/libcxx/include/atomic @@ -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 @@ struct atomic { 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 @@ struct atomic { 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 @@ _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 @@ 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 @@ _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 @@ 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 @@ { 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 @@ { 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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ template _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 @@ _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 @@ template _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 @@ _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 @@ _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 -_LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT -{ - return __o->fetch_add(__op); -} - -template -_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 @@ _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 @@ _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 -_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 -_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 @@ _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 @@ _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 -_LIBCPP_INLINE_VISIBILITY -_Tp* -atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op) _NOEXCEPT -{ - return __o->fetch_sub(__op); -} - -template -_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 @@ _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 @@ _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 -_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 -_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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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); } diff --git a/libcxx/include/version b/libcxx/include/version --- a/libcxx/include/version +++ b/libcxx/include/version @@ -24,8 +24,14 @@ __cpp_lib_array_constexpr 201811L 201603L // C++17 __cpp_lib_as_const 201510L +__cpp_lib_atomic_flag_test 201907L +__cpp_lib_atomic_float 201711L __cpp_lib_atomic_is_always_lock_free 201603L +__cpp_lib_atomic_lock_free_type_aliases 201907L __cpp_lib_atomic_ref 201806L +__cpp_lib_atomic_shared_ptr 201711L +__cpp_lib_atomic_value_initialization 201911L +__cpp_lib_atomic_wait 201907L __cpp_lib_bind_front 201811L __cpp_lib_bit_cast 201806L __cpp_lib_bool_constant 201505L @@ -218,8 +224,26 @@ # 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) diff --git a/libcxx/test/std/atomics/atomics.flag/atomic_flag_test.pass.cpp b/libcxx/test/std/atomics/atomics.flag/atomic_flag_test.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/atomics/atomics.flag/atomic_flag_test.pass.cpp @@ -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 + +// + +// struct atomic_flag + +// bool atomic_flag_test_and_set(volatile atomic_flag*); +// bool atomic_flag_test_and_set(atomic_flag*); + +#include +#include + +#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; +} diff --git a/libcxx/test/std/atomics/atomics.flag/atomic_flag_test_explicit.pass.cpp b/libcxx/test/std/atomics/atomics.flag/atomic_flag_test_explicit.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/atomics/atomics.flag/atomic_flag_test_explicit.pass.cpp @@ -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 + +// + +// struct atomic_flag + +// bool atomic_flag_test_explicit(volatile atomic_flag*, memory_order); +// bool atomic_flag_test_explicit(atomic_flag*, memory_order); + +#include +#include + +#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; +} diff --git a/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp b/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp --- a/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp +++ b/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp @@ -134,6 +134,11 @@ checkLongLongTypes(); static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE), ""); static_assert(std::atomic::is_always_lock_free == (2 == ATOMIC_POINTER_LOCK_FREE), ""); + +#if TEST_STD_VER >= 20 + static_assert(std::atomic::is_always_lock_free, ""); + static_assert(std::atomic::is_always_lock_free, ""); +#endif } int main(int, char**) { run(); return 0; } diff --git a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h --- a/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h +++ b/libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h @@ -23,6 +23,37 @@ { 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 TestFunctor > struct TestEachIntegralType { void operator()() const { @@ -58,8 +89,15 @@ void operator()() const { TestEachIntegralType()(); TestFunctor()(); + TestFunctor()(); +#ifndef __APPLE__ + TestFunctor()(); + TestFunctor()(); +#endif TestFunctor()(); TestFunctor()(); + TestFunctor()(); + TestFunctor()(); } }; diff --git a/libcxx/test/std/atomics/types.pass.cpp b/libcxx/test/std/atomics/types.pass.cpp --- a/libcxx/test/std/atomics/types.pass.cpp +++ b/libcxx/test/std/atomics/types.pass.cpp @@ -30,15 +30,43 @@ #include "test_macros.h" +template +struct test_atomic +{ + test_atomic() + { + A a; (void)a; +#if TEST_STD_VER >= 17 + static_assert((std::is_same_v), ""); +#endif + } +}; + template -void -test_atomic() +struct test_atomic { - A a; (void)a; + test_atomic() + { + A a; (void)a; #if TEST_STD_VER >= 17 - static_assert((std::is_same::value), ""); + static_assert((std::is_same_v), ""); + static_assert((std::is_same_v), ""); #endif -} + } +}; + +template +struct test_atomic +{ + test_atomic() + { + A a; (void)a; +#if TEST_STD_VER >= 17 + static_assert((std::is_same_v), ""); + static_assert((std::is_same_v), ""); +#endif + } +}; template void @@ -46,15 +74,30 @@ { using A = std::atomic; #if TEST_STD_VER >= 17 - static_assert((std::is_same::value), ""); + static_assert((std::is_same_v), ""); #endif - test_atomic(); + test_atomic::value && !std::is_same::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 (); @@ -111,13 +154,19 @@ test (); test(); + test(); +#ifndef __APPLE__ + test(); + test(); +#endif + test(); test(); test(); #if TEST_STD_VER >= 20 - test_atomic(); - test_atomic(); + test(); + test(); /* test>(); */ diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp @@ -15,10 +15,16 @@ // Test the feature test macros defined by -/* 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 @@ -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" diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp @@ -1,4 +1,3 @@ - //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -7,29 +6,53 @@ // //===----------------------------------------------------------------------===// // -// 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 +// Test the feature test macros defined by +/* Constant Value + __cpp_lib_concepts 201806L [C++2a] */ -// XFAIL -// #include -#include +#include #include "test_macros.h" -int main(int, char**) -{ -// ensure that the macros that are supposed to be defined in 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 + +#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 - return 0; -} +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp @@ -1,4 +1,3 @@ - //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. @@ -7,29 +6,62 @@ // //===----------------------------------------------------------------------===// // -// 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 +// Test the feature test macros defined by +/* Constant Value + __cpp_lib_execution 201603L [C++17] */ -// XFAIL -// #include -#include +#include #include "test_macros.h" -int main(int, char**) -{ -// ensure that the macros that are supposed to be defined in 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 + +#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 - return 0; -} +int main(int, char**) { return 0; } diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp @@ -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 diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp --- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp +++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp @@ -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" diff --git a/libcxx/test/support/cmpxchg_loop.h b/libcxx/test/support/cmpxchg_loop.h --- a/libcxx/test/support/cmpxchg_loop.h +++ b/libcxx/test/support/cmpxchg_loop.h @@ -8,8 +8,8 @@ #include -template -bool cmpxchg_weak_loop(A& atomic, T& expected, T desired) { +template +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 @@ return false; } -template -bool cmpxchg_weak_loop(A& atomic, T& expected, T desired, +template +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 @@ return false; } -template -bool c_cmpxchg_weak_loop(A* atomic, T* expected, T desired) { +template +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 @@ return false; } -template -bool c_cmpxchg_weak_loop(A* atomic, T* expected, T desired, +template +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++) { diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -613,6 +613,57 @@ }, "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():