Skip to content

[libc++] cv-qualified types in atomic and atomic_ref (P3323R1) #121414

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 21 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
5afe474
[libc++] cv-qualified types in atomic_ref
dalg24 Dec 31, 2024
fc886c3
[libc++] check that std::atomic is only instantiated for cv-unqualifi…
dalg24 Dec 31, 2024
69d92fa
[libc++] Mark P3323R1 as complete
dalg24 Dec 31, 2024
9c6dd66
[libc++] Add testing for atomic_ref store/load for cv-qualified types
dalg24 Dec 31, 2024
1077d03
Trim trailing empty line in test to please clang-format
dalg24 Dec 31, 2024
28a0107
Add volatile T test for std::atomic
dalg24 Jan 2, 2025
26013d0
Fix GCC error about 2nd argument to the '__atomic' builtins being a p…
dalg24 Jan 3, 2025
ffdda72
Convert compare_exchange_strong test
dalg24 Jan 3, 2025
1b24aeb
Prefer parameter list in requires-expression to avoid declval
dalg24 Jan 7, 2025
a2f7780
Drop unnecessary std:: qualifiers
dalg24 Jan 8, 2025
9ec6b04
Fix constraint on specialization for pointer-to-object types
dalg24 Jan 9, 2025
d878901
Update tests for pointer types such as void*
dalg24 Jan 9, 2025
f350f7f
Undo cxx03 changes
dalg24 Jan 13, 2025
b156123
Merge branch 'main' of https://github.com/llvm/llvm-project into atom…
dalg24 Jan 13, 2025
e0fd1a2
Merge branch 'main' of https://github.com/llvm/llvm-project into atom…
dalg24 Feb 1, 2025
0b96b4c
Add a release note
dalg24 Feb 1, 2025
dcbee5b
Prefer not is_const and not is_volatile when checking cv-unqualified
dalg24 Feb 1, 2025
232a8a5
Prefer using-declaration for value_type in derived classes
dalg24 Feb 1, 2025
d84ec1f
Merge branch 'main' of https://github.com/llvm/llvm-project into atom…
dalg24 Mar 16, 2025
afe849f
Follow pattern suggested by Louis in the tests
dalg24 Mar 16, 2025
b8a4edc
Merge branch 'main' into atomic_ref_cv_qualified_types_p3323
ldionne Mar 31, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libcxx/docs/ReleaseNotes/21.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Implemented Papers
- P2562R1: ``constexpr`` Stable Sorting (`Github <https://github.com/llvm/llvm-project/issues/105360>`__)
- P1222R4: A Standard ``flat_set`` is partially implemented and ``flat_set`` is provided (`Github <https://github.com/llvm/llvm-project/issues/105193>`__)
- P0472R3: Put std::monostate in <utility> (`Github <https://github.com/llvm/llvm-project/issues/127874>`__)
- P3323R1: cv-qualified types in ``atomic`` and ``atomic_ref`` (`Github <https://github.com/llvm/llvm-project/issues/118378>`__)

Improvements and New Features
-----------------------------
Expand Down
2 changes: 1 addition & 1 deletion libcxx/docs/Status/Cxx2cPapers.csv
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
"`P3050R2 <https://wg21.link/P3050R2>`__","Fix C++26 by optimizing ``linalg::conjugated`` for noncomplex value types","2024-11 (Wrocław)","","",""
"`P3396R1 <https://wg21.link/P3396R1>`__","``std::execution`` wording fixes","2024-11 (Wrocław)","","",""
"`P2835R7 <https://wg21.link/P2835R7>`__","Expose ``std::atomic_ref``'s object address","2024-11 (Wrocław)","","",""
"`P3323R1 <https://wg21.link/P3323R1>`__","cv-qualified types in ``atomic`` and ``atomic_ref``","2024-11 (Wrocław)","","",""
"`P3323R1 <https://wg21.link/P3323R1>`__","cv-qualified types in ``atomic`` and ``atomic_ref``","2024-11 (Wrocław)","|Complete|","21","Implemented as DR against C++20."
"`P3508R0 <https://wg21.link/P3508R0>`__","Wording for ""constexpr for specialized memory algorithms""","2024-11 (Wrocław)","","",""
"`P3369R0 <https://wg21.link/P3369R0>`__","constexpr for ``uninitialized_default_construct``","2024-11 (Wrocław)","","",""
"`P3370R1 <https://wg21.link/P3370R1>`__","Add new library headers from C23","2024-11 (Wrocław)","","",""
Expand Down
306 changes: 230 additions & 76 deletions libcxx/include/__atomic/atomic_ref.h

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions libcxx/include/__atomic/support.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
#define _LIBCPP___ATOMIC_SUPPORT_H

#include <__config>
#include <__type_traits/is_const.h>
#include <__type_traits/is_trivially_copyable.h>
#include <__type_traits/is_volatile.h>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
Expand Down Expand Up @@ -114,6 +116,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
template <typename _Tp, typename _Base = __cxx_atomic_base_impl<_Tp> >
struct __cxx_atomic_impl : public _Base {
static_assert(is_trivially_copyable<_Tp>::value, "std::atomic<T> requires that 'T' be a trivially copyable type");
static_assert(!is_const<_Tp>::value && !is_volatile<_Tp>::value,
"std::atomic<T> requires that 'T' be a cv-unqualified type");

_LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default;
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {}
Expand Down
51 changes: 36 additions & 15 deletions libcxx/test/std/atomics/atomics.ref/assign.pass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,50 @@
template <typename T>
struct TestAssign {
void operator()() const {
{
T x(T(1));
std::atomic_ref<T> const a(x);
using Unqualified = std::remove_cv_t<T>;
static_assert(std::is_assignable_v<std::atomic_ref<T>, Unqualified> == !std::is_const_v<T>);

std::same_as<T> decltype(auto) y = (a = T(2));
assert(y == T(2));
assert(x == T(2));
if constexpr (!std::is_const_v<T>) {
{
T x(Unqualified(1));
std::atomic_ref<T> const a(x);

ASSERT_NOEXCEPT(a = T(0));
static_assert(std::is_nothrow_assignable_v<std::atomic_ref<T>, T>);
std::same_as<Unqualified> decltype(auto) y = (a = Unqualified(2));
assert(y == Unqualified(2));
assert(const_cast<Unqualified const&>(x) == Unqualified(2));

static_assert(!std::is_copy_assignable_v<std::atomic_ref<T>>);
}
ASSERT_NOEXCEPT(a = Unqualified(0));
static_assert(std::is_nothrow_assignable_v<std::atomic_ref<T>, Unqualified>);
static_assert(!std::is_copy_assignable_v<std::atomic_ref<T>>);
}

{
auto assign = [](std::atomic_ref<T> const& y, T, T new_val) { y = new_val; };
auto load = [](std::atomic_ref<T> const& y) { return y.load(); };
test_seq_cst<T>(assign, load);
{
auto assign = [](std::atomic_ref<T> const& y, T const&, T const& new_val) {
y = const_cast<Unqualified const&>(new_val);
};
auto load = [](std::atomic_ref<T> const& y) { return y.load(); };
test_seq_cst<T>(assign, load);
}
}
}
};

template <template <class...> class F>
struct CallWithCVQualifiers {
template <class T>
struct apply {
void operator()() const {
F<T>()();
F<T const>()();
if constexpr (std::atomic_ref<T>::is_always_lock_free) {
F<T volatile>()();
F<T const volatile>()();
}
}
};
};

int main(int, char**) {
TestEachAtomicType<TestAssign>()();
TestEachAtomicType<CallWithCVQualifiers<TestAssign>::apply>()();
return 0;
}
Loading
Loading