[libcxx-commits] [libcxx] fc4bff0 - Update atomic feature macros, synopsis, signatures to match C++20. Improve test coverage for non-lock-free atomics.
Olivier Giroux via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Sep 9 10:00:28 PDT 2020
Author: Olivier Giroux
Date: 2020-09-09T10:00:09-07:00
New Revision: fc4bff0cd37fa84ee74e6dff7170b643df3ffa42
URL: https://github.com/llvm/llvm-project/commit/fc4bff0cd37fa84ee74e6dff7170b643df3ffa42
DIFF: https://github.com/llvm/llvm-project/commit/fc4bff0cd37fa84ee74e6dff7170b643df3ffa42.diff
LOG: Update atomic feature macros, synopsis, signatures to match C++20. Improve test coverage for non-lock-free atomics.
Added:
libcxx/test/std/atomics/atomics.flag/atomic_flag_test.pass.cpp
libcxx/test/std/atomics/atomics.flag/atomic_flag_test_explicit.pass.cpp
Modified:
libcxx/docs/FeatureTestMacroTable.rst
libcxx/include/atomic
libcxx/include/version
libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
libcxx/test/std/atomics/atomics.types.operations/atomics.types.operations.req/atomic_helpers.h
libcxx/test/std/atomics/types.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/atomic.version.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/concepts.version.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/execution.version.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/memory.version.pass.cpp
libcxx/test/std/language.support/support.limits/support.limits.general/version.version.pass.cpp
libcxx/test/support/cmpxchg_loop.h
libcxx/utils/generate_feature_test_macro_components.py
Removed:
################################################################################
diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index f5c6e5b8251a..61773381c15f 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -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*
diff --git a/libcxx/include/atomic b/libcxx/include/atomic
index 9c2898653788..be81f6491edf 100644
--- 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 @@ template <>
struct atomic<integral>
{
using value_type = integral;
+ using
diff erence_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
diff erence_type = ptr
diff _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
diff erence_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 ptr
diff _t
diff erence_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>::
diff erence_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, ptr
diff _t __op) _NOEXCEPT
-{
- return __o->fetch_add(__op);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp*
-atomic_fetch_add(atomic<_Tp*>* __o, ptr
diff _t __op) _NOEXCEPT
+atomic_fetch_add(atomic<_Tp>* __o, typename atomic<_Tp>::
diff erence_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>::
diff erence_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, ptr
diff _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, ptr
diff _t __op, memory_order __m) _NOEXCEPT
+atomic_fetch_add_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::
diff erence_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>::
diff erence_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, ptr
diff _t __op) _NOEXCEPT
-{
- return __o->fetch_sub(__op);
-}
-
-template <class _Tp>
-_LIBCPP_INLINE_VISIBILITY
-_Tp*
-atomic_fetch_sub(atomic<_Tp*>* __o, ptr
diff _t __op) _NOEXCEPT
+atomic_fetch_sub(atomic<_Tp>* __o, typename atomic<_Tp>::
diff erence_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>::
diff erence_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, ptr
diff _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, ptr
diff _t __op, memory_order __m) _NOEXCEPT
+atomic_fetch_sub_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::
diff erence_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);
}
diff --git a/libcxx/include/version b/libcxx/include/version
index dc53be3937c4..d18da3d14690 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -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)
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
index 000000000000..22e4b66d45c5
--- /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
+
+// <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;
+}
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
index 000000000000..45ac737b5984
--- /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
+
+// <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;
+}
diff --git a/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp b/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
index 34a068918286..8dd8c345592b 100644
--- a/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
+++ b/libcxx/test/std/atomics/atomics.lockfree/isalwayslockfree.pass.cpp
@@ -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; }
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
index 65676339c742..1cb3a3d11114 100644
--- 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 @@ 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>()();
}
};
diff --git a/libcxx/test/std/atomics/types.pass.cpp b/libcxx/test/std/atomics/types.pass.cpp
index f891f90e116b..5740b758035e 100644
--- 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 <class A, bool Integral>
+struct test_atomic
+{
+ test_atomic()
+ {
+ A a; (void)a;
+#if TEST_STD_VER >= 17
+ static_assert((std::is_same_v<typename A::value_type, decltype(a.load())>), "");
+#endif
+ }
+};
+
template <class A>
-void
-test_atomic()
+struct test_atomic<A, true>
{
- 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())>), "");
+ static_assert((std::is_same_v<typename A::value_type, typename A::
diff erence_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::
diff erence_type, ptr
diff _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>>();
*/
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
index d8f6f548cd23..d4c63edb5b8a 100644
--- 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 <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"
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
index 16febf8d3e24..9ec2157d974c 100644
--- 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 @@
//
//===----------------------------------------------------------------------===//
//
-// <concepts> feature macros
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <concepts>
-/* Constant Value
- __cpp_lib_concepts 201806L
+// 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
+
+#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
index b05f41bb1731..1244efa4aeba 100644
--- 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 @@
//
//===----------------------------------------------------------------------===//
//
-// <execution> feature macros
+// WARNING: This test was generated by generate_feature_test_macro_components.py
+// and should not be edited manually.
+
+// <execution>
-/* Constant Value
- __cpp_lib_execution 201603L
+// 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
+
+#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
index 6c845d71febd..0117fd83a60c 100644
--- 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
index afbee586df3c..46b2e1f21d18 100644
--- 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
index 50bd00a30bdb..e34160609813 100644
--- a/libcxx/test/support/cmpxchg_loop.h
+++ b/libcxx/test/support/cmpxchg_loop.h
@@ -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++) {
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index 6ad1a1856989..211702e9982c 100755
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -613,6 +613,57 @@ def add_version_header(tc):
},
"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():
More information about the libcxx-commits
mailing list