2727
2828_LIBCPP_BEGIN_NAMESPACE_STD
2929
30+ #if _LIBCPP_STD_VER >= 20
31+ template <class _Tp , bool __lock_free>
32+ inline constexpr bool __deprecated_if_not_always_lock_free = true ;
33+
34+ template <class _Tp >
35+ [[deprecated(" volatile atomic operations are deprecated when std::atomic<T>::is_always_lock_free is false" )]]
36+ inline constexpr bool __deprecated_if_not_always_lock_free<_Tp, false > = true ;
37+ # define _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __is_always_lock_free ) \
38+ static_assert (__deprecated_if_not_always_lock_free<_Tp, __is_always_lock_free>)
39+ #else
40+ # define _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __is_always_lock_free ) \
41+ {}
42+ #endif
43+
3044template <class _Tp , bool = is_integral<_Tp>::value && !is_same<_Tp, bool >::value>
3145struct __atomic_base // false
3246{
@@ -44,6 +58,7 @@ struct __atomic_base // false
4458 }
4559 _LIBCPP_HIDE_FROM_ABI void store (_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT
4660 _LIBCPP_CHECK_STORE_MEMORY_ORDER(__m) {
61+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, is_always_lock_free);
4762 std::__cxx_atomic_store (std::addressof (__a_), __d, __m);
4863 }
4964 _LIBCPP_HIDE_FROM_ABI void store (_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT
@@ -52,15 +67,20 @@ struct __atomic_base // false
5267 }
5368 _LIBCPP_HIDE_FROM_ABI _Tp load (memory_order __m = memory_order_seq_cst) const volatile _NOEXCEPT
5469 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
70+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, is_always_lock_free);
5571 return std::__cxx_atomic_load (std::addressof (__a_), __m);
5672 }
5773 _LIBCPP_HIDE_FROM_ABI _Tp load (memory_order __m = memory_order_seq_cst) const _NOEXCEPT
5874 _LIBCPP_CHECK_LOAD_MEMORY_ORDER(__m) {
5975 return std::__cxx_atomic_load (std::addressof (__a_), __m);
6076 }
61- _LIBCPP_HIDE_FROM_ABI operator _Tp () const volatile _NOEXCEPT { return load (); }
77+ _LIBCPP_HIDE_FROM_ABI operator _Tp () const volatile _NOEXCEPT {
78+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, is_always_lock_free);
79+ return load ();
80+ }
6281 _LIBCPP_HIDE_FROM_ABI operator _Tp () const _NOEXCEPT { return load (); }
6382 _LIBCPP_HIDE_FROM_ABI _Tp exchange (_Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
83+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, is_always_lock_free);
6484 return std::__cxx_atomic_exchange (std::addressof (__a_), __d, __m);
6585 }
6686 _LIBCPP_HIDE_FROM_ABI _Tp exchange (_Tp __d, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
@@ -69,6 +89,7 @@ struct __atomic_base // false
6989 _LIBCPP_HIDE_FROM_ABI bool
7090 compare_exchange_weak (_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
7191 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER (__s, __f) {
92+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, is_always_lock_free);
7293 return std::__cxx_atomic_compare_exchange_weak (std::addressof (__a_), std::addressof (__e), __d, __s, __f);
7394 }
7495 _LIBCPP_HIDE_FROM_ABI bool compare_exchange_weak (_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
@@ -78,6 +99,7 @@ struct __atomic_base // false
7899 _LIBCPP_HIDE_FROM_ABI bool
79100 compare_exchange_strong (_Tp& __e, _Tp __d, memory_order __s, memory_order __f) volatile _NOEXCEPT
80101 _LIBCPP_CHECK_EXCHANGE_MEMORY_ORDER (__s, __f) {
102+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, is_always_lock_free);
81103 return std::__cxx_atomic_compare_exchange_strong (std::addressof (__a_), std::addressof (__e), __d, __s, __f);
82104 }
83105 _LIBCPP_HIDE_FROM_ABI bool compare_exchange_strong (_Tp& __e, _Tp __d, memory_order __s, memory_order __f) _NOEXCEPT
@@ -86,6 +108,7 @@ struct __atomic_base // false
86108 }
87109 _LIBCPP_HIDE_FROM_ABI bool
88110 compare_exchange_weak (_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
111+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, is_always_lock_free);
89112 return std::__cxx_atomic_compare_exchange_weak (std::addressof (__a_), std::addressof (__e), __d, __m, __m);
90113 }
91114 _LIBCPP_HIDE_FROM_ABI bool
@@ -94,6 +117,7 @@ struct __atomic_base // false
94117 }
95118 _LIBCPP_HIDE_FROM_ABI bool
96119 compare_exchange_strong (_Tp& __e, _Tp __d, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
120+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, is_always_lock_free);
97121 return std::__cxx_atomic_compare_exchange_strong (std::addressof (__a_), std::addressof (__e), __d, __m, __m);
98122 }
99123 _LIBCPP_HIDE_FROM_ABI bool
@@ -142,54 +166,112 @@ struct __atomic_base<_Tp, true> : public __atomic_base<_Tp, false> {
142166 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR __atomic_base (_Tp __d) _NOEXCEPT : __base(__d) {}
143167
144168 _LIBCPP_HIDE_FROM_ABI _Tp fetch_add (_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
169+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
145170 return std::__cxx_atomic_fetch_add (std::addressof (this ->__a_ ), __op, __m);
146171 }
172+
147173 _LIBCPP_HIDE_FROM_ABI _Tp fetch_add (_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
148174 return std::__cxx_atomic_fetch_add (std::addressof (this ->__a_ ), __op, __m);
149175 }
176+
150177 _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub (_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
178+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
151179 return std::__cxx_atomic_fetch_sub (std::addressof (this ->__a_ ), __op, __m);
152180 }
181+
153182 _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub (_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
154183 return std::__cxx_atomic_fetch_sub (std::addressof (this ->__a_ ), __op, __m);
155184 }
185+
156186 _LIBCPP_HIDE_FROM_ABI _Tp fetch_and (_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
187+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
157188 return std::__cxx_atomic_fetch_and (std::addressof (this ->__a_ ), __op, __m);
158189 }
190+
159191 _LIBCPP_HIDE_FROM_ABI _Tp fetch_and (_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
160192 return std::__cxx_atomic_fetch_and (std::addressof (this ->__a_ ), __op, __m);
161193 }
194+
162195 _LIBCPP_HIDE_FROM_ABI _Tp fetch_or (_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
196+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
163197 return std::__cxx_atomic_fetch_or (std::addressof (this ->__a_ ), __op, __m);
164198 }
199+
165200 _LIBCPP_HIDE_FROM_ABI _Tp fetch_or (_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
166201 return std::__cxx_atomic_fetch_or (std::addressof (this ->__a_ ), __op, __m);
167202 }
203+
168204 _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor (_Tp __op, memory_order __m = memory_order_seq_cst) volatile _NOEXCEPT {
205+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
169206 return std::__cxx_atomic_fetch_xor (std::addressof (this ->__a_ ), __op, __m);
170207 }
208+
171209 _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor (_Tp __op, memory_order __m = memory_order_seq_cst) _NOEXCEPT {
172210 return std::__cxx_atomic_fetch_xor (std::addressof (this ->__a_ ), __op, __m);
173211 }
174212
175- _LIBCPP_HIDE_FROM_ABI _Tp operator ++(int ) volatile _NOEXCEPT { return fetch_add (_Tp (1 )); }
176213 _LIBCPP_HIDE_FROM_ABI _Tp operator ++(int ) _NOEXCEPT { return fetch_add (_Tp (1 )); }
177- _LIBCPP_HIDE_FROM_ABI _Tp operator --(int ) volatile _NOEXCEPT { return fetch_sub (_Tp (1 )); }
214+
215+ _LIBCPP_HIDE_FROM_ABI _Tp operator ++(int ) volatile _NOEXCEPT {
216+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
217+ return fetch_add (_Tp (1 ));
218+ }
219+
178220 _LIBCPP_HIDE_FROM_ABI _Tp operator --(int ) _NOEXCEPT { return fetch_sub (_Tp (1 )); }
179- _LIBCPP_HIDE_FROM_ABI _Tp operator ++() volatile _NOEXCEPT { return fetch_add (_Tp (1 )) + _Tp (1 ); }
221+
222+ _LIBCPP_HIDE_FROM_ABI _Tp operator --(int ) volatile _NOEXCEPT {
223+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
224+ return fetch_sub (_Tp (1 ));
225+ }
226+
180227 _LIBCPP_HIDE_FROM_ABI _Tp operator ++() _NOEXCEPT { return fetch_add (_Tp (1 )) + _Tp (1 ); }
181- _LIBCPP_HIDE_FROM_ABI _Tp operator --() volatile _NOEXCEPT { return fetch_sub (_Tp (1 )) - _Tp (1 ); }
228+
229+ _LIBCPP_HIDE_FROM_ABI _Tp operator ++() volatile _NOEXCEPT {
230+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
231+ return fetch_add (_Tp (1 )) + _Tp (1 );
232+ }
233+
182234 _LIBCPP_HIDE_FROM_ABI _Tp operator --() _NOEXCEPT { return fetch_sub (_Tp (1 )) - _Tp (1 ); }
183- _LIBCPP_HIDE_FROM_ABI _Tp operator +=(_Tp __op) volatile _NOEXCEPT { return fetch_add (__op) + __op; }
235+
236+ _LIBCPP_HIDE_FROM_ABI _Tp operator --() volatile _NOEXCEPT {
237+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
238+ return fetch_sub (_Tp (1 )) - _Tp (1 );
239+ }
240+
184241 _LIBCPP_HIDE_FROM_ABI _Tp operator +=(_Tp __op) _NOEXCEPT { return fetch_add (__op) + __op; }
185- _LIBCPP_HIDE_FROM_ABI _Tp operator -=(_Tp __op) volatile _NOEXCEPT { return fetch_sub (__op) - __op; }
242+
243+ _LIBCPP_HIDE_FROM_ABI _Tp operator +=(_Tp __op) volatile _NOEXCEPT {
244+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
245+ return fetch_add (__op) + __op;
246+ }
247+
186248 _LIBCPP_HIDE_FROM_ABI _Tp operator -=(_Tp __op) _NOEXCEPT { return fetch_sub (__op) - __op; }
187- _LIBCPP_HIDE_FROM_ABI _Tp operator &=(_Tp __op) volatile _NOEXCEPT { return fetch_and (__op) & __op; }
249+
250+ _LIBCPP_HIDE_FROM_ABI _Tp operator -=(_Tp __op) volatile _NOEXCEPT {
251+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
252+ return fetch_sub (__op) - __op;
253+ }
254+
188255 _LIBCPP_HIDE_FROM_ABI _Tp operator &=(_Tp __op) _NOEXCEPT { return fetch_and (__op) & __op; }
189- _LIBCPP_HIDE_FROM_ABI _Tp operator |=(_Tp __op) volatile _NOEXCEPT { return fetch_or (__op) | __op; }
256+
257+ _LIBCPP_HIDE_FROM_ABI _Tp operator &=(_Tp __op) volatile _NOEXCEPT {
258+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
259+ return fetch_and (__op) & __op;
260+ }
261+
190262 _LIBCPP_HIDE_FROM_ABI _Tp operator |=(_Tp __op) _NOEXCEPT { return fetch_or (__op) | __op; }
191- _LIBCPP_HIDE_FROM_ABI _Tp operator ^=(_Tp __op) volatile _NOEXCEPT { return fetch_xor (__op) ^ __op; }
263+
264+ _LIBCPP_HIDE_FROM_ABI _Tp operator |=(_Tp __op) volatile _NOEXCEPT {
265+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
266+ return fetch_or (__op) | __op;
267+ }
268+
192269 _LIBCPP_HIDE_FROM_ABI _Tp operator ^=(_Tp __op) _NOEXCEPT { return fetch_xor (__op) ^ __op; }
270+
271+ _LIBCPP_HIDE_FROM_ABI _Tp operator ^=(_Tp __op) volatile _NOEXCEPT {
272+ _LIBCPP_DEPRECATED_NOT_ALWAYS_LOCK_FREE (_Tp, __base::is_always_lock_free);
273+ return fetch_xor (__op) ^ __op;
274+ }
193275};
194276
195277// Here we need _IsIntegral because the default template argument is not enough
0 commit comments