|
15 | 15 | #include <__atomic/is_always_lock_free.h>
|
16 | 16 | #include <__config>
|
17 | 17 | #include <__type_traits/conditional.h>
|
| 18 | +#include <__type_traits/make_unsigned.h> |
18 | 19 | #include <cstddef>
|
19 | 20 | #include <cstdint>
|
20 | 21 | #include <cstdlib>
|
@@ -80,36 +81,30 @@ using atomic_ptrdiff_t = atomic<ptrdiff_t>;
|
80 | 81 | using atomic_intmax_t = atomic<intmax_t>;
|
81 | 82 | using atomic_uintmax_t = atomic<uintmax_t>;
|
82 | 83 |
|
83 |
| -// atomic_*_lock_free : prefer the contention type most highly, then the largest lock-free type |
| 84 | +// C++20 atomic_{signed,unsigned}_lock_free: prefer the contention type most highly, then the largest lock-free type |
| 85 | +#if _LIBCPP_STD_VER >= 20 |
| 86 | +# if ATOMIC_LLONG_LOCK_FREE == 2 |
| 87 | +using __largest_lock_free_type = long long; |
| 88 | +# elif ATOMIC_INT_LOCK_FREE == 2 |
| 89 | +using __largest_lock_free_type = int; |
| 90 | +# elif ATOMIC_SHORT_LOCK_FREE == 2 |
| 91 | +using __largest_lock_free_type = short; |
| 92 | +# elif ATOMIC_CHAR_LOCK_FREE == 2 |
| 93 | +using __largest_lock_free_type = char; |
| 94 | +# else |
| 95 | +# define _LIBCPP_NO_LOCK_FREE_TYPES // There are no lockfree types (this can happen in freestanding) |
| 96 | +# endif |
84 | 97 |
|
85 |
| -#if _LIBCPP_STD_VER >= 17 |
86 |
| -# define _LIBCPP_CONTENTION_LOCK_FREE ::std::__libcpp_is_always_lock_free<__cxx_contention_t>::__value |
87 |
| -#else |
88 |
| -# define _LIBCPP_CONTENTION_LOCK_FREE false |
89 |
| -#endif |
90 |
| - |
91 |
| -#if ATOMIC_LLONG_LOCK_FREE == 2 |
92 |
| -using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, long long>; |
93 |
| -using __libcpp_unsigned_lock_free = |
94 |
| - __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned long long>; |
95 |
| -#elif ATOMIC_INT_LOCK_FREE == 2 |
96 |
| -using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, int>; |
97 |
| -using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned int>; |
98 |
| -#elif ATOMIC_SHORT_LOCK_FREE == 2 |
99 |
| -using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, short>; |
100 |
| -using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned short>; |
101 |
| -#elif ATOMIC_CHAR_LOCK_FREE == 2 |
102 |
| -using __libcpp_signed_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, char>; |
103 |
| -using __libcpp_unsigned_lock_free = __conditional_t<_LIBCPP_CONTENTION_LOCK_FREE, __cxx_contention_t, unsigned char>; |
104 |
| -#else |
105 |
| -// No signed/unsigned lock-free types |
106 |
| -# define _LIBCPP_NO_LOCK_FREE_TYPES |
107 |
| -#endif |
| 98 | +# ifndef _LIBCPP_NO_LOCK_FREE_TYPES |
| 99 | +using __contention_t_or_largest = |
| 100 | + __conditional_t<__libcpp_is_always_lock_free<__cxx_contention_t>::__value, |
| 101 | + __cxx_contention_t, |
| 102 | + __largest_lock_free_type>; |
108 | 103 |
|
109 |
| -#if !defined(_LIBCPP_NO_LOCK_FREE_TYPES) |
110 |
| -using atomic_signed_lock_free = atomic<__libcpp_signed_lock_free>; |
111 |
| -using atomic_unsigned_lock_free = atomic<__libcpp_unsigned_lock_free>; |
112 |
| -#endif |
| 104 | +using atomic_signed_lock_free = atomic<__contention_t_or_largest>; |
| 105 | +using atomic_unsigned_lock_free = atomic<make_unsigned_t<__contention_t_or_largest>>; |
| 106 | +# endif // !_LIBCPP_NO_LOCK_FREE_TYPES |
| 107 | +#endif // C++20 |
113 | 108 |
|
114 | 109 | _LIBCPP_END_NAMESPACE_STD
|
115 | 110 |
|
|
0 commit comments