[libcxx-commits] [libcxx] [libc++] cv-qualified types in atomic and atomic_ref (P3323R1) (PR #121414)
Louis Dionne via libcxx-commits
libcxx-commits at lists.llvm.org
Fri Jan 31 12:34:41 PST 2025
================
@@ -271,43 +311,101 @@ struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> {
_LIBCPP_HIDE_FROM_ABI atomic_ref(const atomic_ref&) noexcept = default;
- _LIBCPP_HIDE_FROM_ABI _Tp operator=(_Tp __desired) const noexcept { return __base::operator=(__desired); }
+ _LIBCPP_HIDE_FROM_ABI value_type operator=(value_type __desired) const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return __base::operator=(__desired);
+ }
atomic_ref& operator=(const atomic_ref&) = delete;
- _LIBCPP_HIDE_FROM_ABI _Tp fetch_add(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
+ _LIBCPP_HIDE_FROM_ABI value_type
+ fetch_add(value_type __arg, memory_order __order = memory_order_seq_cst) const noexcept
+ requires(!is_const_v<value_type>)
+ {
return __atomic_fetch_add(this->__ptr_, __arg, std::__to_gcc_order(__order));
}
- _LIBCPP_HIDE_FROM_ABI _Tp fetch_sub(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
+ _LIBCPP_HIDE_FROM_ABI value_type
+ fetch_sub(value_type __arg, memory_order __order = memory_order_seq_cst) const noexcept
+ requires(!is_const_v<value_type>)
+ {
return __atomic_fetch_sub(this->__ptr_, __arg, std::__to_gcc_order(__order));
}
- _LIBCPP_HIDE_FROM_ABI _Tp fetch_and(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
+ _LIBCPP_HIDE_FROM_ABI value_type
+ fetch_and(value_type __arg, memory_order __order = memory_order_seq_cst) const noexcept
+ requires(!is_const_v<value_type>)
+ {
return __atomic_fetch_and(this->__ptr_, __arg, std::__to_gcc_order(__order));
}
- _LIBCPP_HIDE_FROM_ABI _Tp fetch_or(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
+ _LIBCPP_HIDE_FROM_ABI value_type
+ fetch_or(value_type __arg, memory_order __order = memory_order_seq_cst) const noexcept
+ requires(!is_const_v<value_type>)
+ {
return __atomic_fetch_or(this->__ptr_, __arg, std::__to_gcc_order(__order));
}
- _LIBCPP_HIDE_FROM_ABI _Tp fetch_xor(_Tp __arg, memory_order __order = memory_order_seq_cst) const noexcept {
+ _LIBCPP_HIDE_FROM_ABI value_type
+ fetch_xor(value_type __arg, memory_order __order = memory_order_seq_cst) const noexcept
+ requires(!is_const_v<value_type>)
+ {
return __atomic_fetch_xor(this->__ptr_, __arg, std::__to_gcc_order(__order));
}
- _LIBCPP_HIDE_FROM_ABI _Tp operator++(int) const noexcept { return fetch_add(_Tp(1)); }
- _LIBCPP_HIDE_FROM_ABI _Tp operator--(int) const noexcept { return fetch_sub(_Tp(1)); }
- _LIBCPP_HIDE_FROM_ABI _Tp operator++() const noexcept { return fetch_add(_Tp(1)) + _Tp(1); }
- _LIBCPP_HIDE_FROM_ABI _Tp operator--() const noexcept { return fetch_sub(_Tp(1)) - _Tp(1); }
- _LIBCPP_HIDE_FROM_ABI _Tp operator+=(_Tp __arg) const noexcept { return fetch_add(__arg) + __arg; }
- _LIBCPP_HIDE_FROM_ABI _Tp operator-=(_Tp __arg) const noexcept { return fetch_sub(__arg) - __arg; }
- _LIBCPP_HIDE_FROM_ABI _Tp operator&=(_Tp __arg) const noexcept { return fetch_and(__arg) & __arg; }
- _LIBCPP_HIDE_FROM_ABI _Tp operator|=(_Tp __arg) const noexcept { return fetch_or(__arg) | __arg; }
- _LIBCPP_HIDE_FROM_ABI _Tp operator^=(_Tp __arg) const noexcept { return fetch_xor(__arg) ^ __arg; }
+ _LIBCPP_HIDE_FROM_ABI value_type operator++(int) const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return fetch_add(value_type(1));
+ }
+ _LIBCPP_HIDE_FROM_ABI value_type operator--(int) const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return fetch_sub(value_type(1));
+ }
+ _LIBCPP_HIDE_FROM_ABI value_type operator++() const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return fetch_add(value_type(1)) + value_type(1);
+ }
+ _LIBCPP_HIDE_FROM_ABI value_type operator--() const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return fetch_sub(value_type(1)) - value_type(1);
+ }
+ _LIBCPP_HIDE_FROM_ABI value_type operator+=(value_type __arg) const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return fetch_add(__arg) + __arg;
+ }
+ _LIBCPP_HIDE_FROM_ABI value_type operator-=(value_type __arg) const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return fetch_sub(__arg) - __arg;
+ }
+ _LIBCPP_HIDE_FROM_ABI value_type operator&=(value_type __arg) const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return fetch_and(__arg) & __arg;
+ }
+ _LIBCPP_HIDE_FROM_ABI value_type operator|=(value_type __arg) const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return fetch_or(__arg) | __arg;
+ }
+ _LIBCPP_HIDE_FROM_ABI value_type operator^=(value_type __arg) const noexcept
+ requires(!is_const_v<_Tp>)
+ {
+ return fetch_xor(__arg) ^ __arg;
+ }
};
template <class _Tp>
- requires std::floating_point<_Tp>
+ requires floating_point<_Tp>
struct atomic_ref<_Tp> : public __atomic_ref_base<_Tp> {
using __base _LIBCPP_NODEBUG = __atomic_ref_base<_Tp>;
+ static_assert(__base::is_always_lock_free || !is_volatile_v<_Tp>);
----------------
ldionne wrote:
Here and above, let's add a short error message. We can maybe say that the Standard disallows this along with a rationale if there's one. As-is, users could be left thinking that it's an artifact of our implementation or something. Let's be explicit about the fact that the Standard doesn't allow it.
https://github.com/llvm/llvm-project/pull/121414
More information about the libcxx-commits
mailing list