Skip to content

[libc++] LWG-4021 "mdspan::is_always_meow() should be noexcept", use LIBCPP_STATIC_ASSERT for noexcept strengthening #74254

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

Merged
merged 4 commits into from
Dec 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 8 additions & 3 deletions libcxx/include/__mdspan/mdspan.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,14 @@ class mdspan {
_LIBCPP_HIDE_FROM_ABI constexpr const mapping_type& mapping() const noexcept { return __map_; };
_LIBCPP_HIDE_FROM_ABI constexpr const accessor_type& accessor() const noexcept { return __acc_; };

_LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() { return mapping_type::is_always_unique(); };
_LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() { return mapping_type::is_always_exhaustive(); };
_LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() { return mapping_type::is_always_strided(); };
// per LWG-4021 "mdspan::is_always_meow() should be noexcept"
_LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_unique() noexcept { return mapping_type::is_always_unique(); };
_LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_exhaustive() noexcept {
return mapping_type::is_always_exhaustive();
};
_LIBCPP_HIDE_FROM_ABI static constexpr bool is_always_strided() noexcept {
return mapping_type::is_always_strided();
};

_LIBCPP_HIDE_FROM_ABI constexpr bool is_unique() const { return __map_.is_unique(); };
_LIBCPP_HIDE_FROM_ABI constexpr bool is_exhaustive() const { return __map_.is_exhaustive(); };
Expand Down
7 changes: 4 additions & 3 deletions libcxx/include/mdspan
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,12 @@ namespace std {
constexpr const mapping_type& mapping() const noexcept { return map_; }
constexpr const accessor_type& accessor() const noexcept { return acc_; }

static constexpr bool is_always_unique()
// per LWG-4021 "mdspan::is_always_meow() should be noexcept"
static constexpr bool is_always_unique() noexcept
{ return mapping_type::is_always_unique(); }
static constexpr bool is_always_exhaustive()
static constexpr bool is_always_exhaustive() noexcept
{ return mapping_type::is_always_exhaustive(); }
static constexpr bool is_always_strided()
static constexpr bool is_always_strided() noexcept
{ return mapping_type::is_always_strided(); }

constexpr bool is_unique() const
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ test_mdspan_ctor_array(const H& handle, const M& map, const A&, std::array<typen
}
}

static_assert(!noexcept(MDS(handle, exts)));
LIBCPP_STATIC_ASSERT(!noexcept(MDS(handle, exts)));

static_assert(check_mdspan_ctor_implicit<MDS, decltype(exts)> == (N == MDS::rank_dynamic()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&) {
assert((H::move_counter() == 1));
}
}
static_assert(!noexcept(MDS(handle, map.extents())));
LIBCPP_STATIC_ASSERT(!noexcept(MDS(handle, map.extents())));
assert(m.extents() == map.extents());
if constexpr (std::equality_comparable<H>)
assert(m.data_handle() == handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A&) {
assert((H::move_counter() == 1));
}
}
static_assert(!noexcept(MDS(handle, map)));
LIBCPP_STATIC_ASSERT(!noexcept(MDS(handle, map)));
assert(m.extents() == map.extents());
if constexpr (std::equality_comparable<H>)
assert(m.data_handle() == handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) {
assert((H::move_counter() == 1));
}
}
static_assert(!noexcept(MDS(handle, map, acc)));
LIBCPP_STATIC_ASSERT(!noexcept(MDS(handle, map, acc)));
assert(m.extents() == map.extents());
if constexpr (std::equality_comparable<H>)
assert(m.data_handle() == handle);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ test_mdspan_ctor_span(const H& handle, const M& map, const A&, std::span<typenam
}
}

static_assert(!noexcept(MDS(handle, exts)));
LIBCPP_STATIC_ASSERT(!noexcept(MDS(handle, exts)));

static_assert(check_mdspan_ctor_implicit<MDS, decltype(exts)> == (N == MDS::rank_dynamic()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,12 @@
// constexpr const data_handle_type& data_handle() const noexcept { return ptr_; }
// constexpr const mapping_type& mapping() const noexcept { return map_; }
// constexpr const accessor_type& accessor() const noexcept { return acc_; }
// static constexpr bool is_always_unique()
// /* per LWG-4021 "mdspan::is_always_meow() should be noexcept" */
// static constexpr bool is_always_unique() noexcept
// { return mapping_type::is_always_unique(); }
// static constexpr bool is_always_exhaustive()
// static constexpr bool is_always_exhaustive() noexcept
// { return mapping_type::is_always_exhaustive(); }
// static constexpr bool is_always_strided()
// static constexpr bool is_always_strided() noexcept
// { return mapping_type::is_always_strided(); }
//
// constexpr bool is_unique() const
Expand Down Expand Up @@ -141,15 +142,16 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) {
ASSERT_SAME_TYPE(decltype(m.is_unique()), bool);
ASSERT_SAME_TYPE(decltype(m.is_exhaustive()), bool);
ASSERT_SAME_TYPE(decltype(m.is_strided()), bool);
assert(!noexcept(MDS::is_always_unique()));
assert(!noexcept(MDS::is_always_exhaustive()));
assert(!noexcept(MDS::is_always_strided()));
assert(!noexcept(m.is_unique()));
assert(!noexcept(m.is_exhaustive()));
assert(!noexcept(m.is_strided()));
assert(MDS::is_always_unique() == M::is_always_unique());
assert(MDS::is_always_exhaustive() == M::is_always_exhaustive());
assert(MDS::is_always_strided() == M::is_always_strided());
// per LWG-4021 "mdspan::is_always_meow() should be noexcept"
static_assert(noexcept(MDS::is_always_unique()));
static_assert(noexcept(MDS::is_always_exhaustive()));
static_assert(noexcept(MDS::is_always_strided()));
LIBCPP_STATIC_ASSERT(!noexcept(m.is_unique()));
LIBCPP_STATIC_ASSERT(!noexcept(m.is_exhaustive()));
LIBCPP_STATIC_ASSERT(!noexcept(m.is_strided()));
static_assert(MDS::is_always_unique() == M::is_always_unique());
static_assert(MDS::is_always_exhaustive() == M::is_always_exhaustive());
static_assert(MDS::is_always_strided() == M::is_always_strided());
assert(m.is_unique() == map.is_unique());
assert(m.is_exhaustive() == map.is_exhaustive());
assert(m.is_strided() == map.is_strided());
Expand All @@ -159,7 +161,7 @@ constexpr void test_mdspan_types(const H& handle, const M& map, const A& acc) {
if (m.is_strided()) {
for (typename MDS::rank_type r = 0; r < MDS::rank(); r++) {
ASSERT_SAME_TYPE(decltype(m.stride(r)), typename MDS::index_type);
assert(!noexcept(m.stride(r)));
LIBCPP_STATIC_ASSERT(!noexcept(m.stride(r)));
assert(m.stride(r) == map.stride(r));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static void test() {
{
std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_not_empty<CharT>> buf1;
std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_not_empty<CharT>> buf;
static_assert(!noexcept(buf.swap(buf1)));
LIBCPP_STATIC_ASSERT(!noexcept(buf.swap(buf1)));
}
{
std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_not_empty<CharT>> buf1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static void test() {
{
std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_not_empty<CharT>> buf1;
std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_not_empty<CharT>> buf;
static_assert(!noexcept(swap(buf, buf1)));
LIBCPP_STATIC_ASSERT(!noexcept(swap(buf, buf1)));
}
{
std::basic_stringbuf<CharT, std::char_traits<CharT>, test_alloc_propagate_on_container_swap_not_empty<CharT>> buf1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,15 @@ constexpr bool test() {

auto unscoped = check_unqualified_lookup::unscoped_enum::a;
assert(std::ranges::iter_move(unscoped) == check_unqualified_lookup::unscoped_enum::a);
assert(!noexcept(std::ranges::iter_move(unscoped)));
static_assert(!noexcept(std::ranges::iter_move(unscoped)));

auto scoped = check_unqualified_lookup::scoped_enum::a;
assert(std::ranges::iter_move(scoped) == nullptr);
assert(noexcept(std::ranges::iter_move(scoped)));
static_assert(noexcept(std::ranges::iter_move(scoped)));

auto some_union = check_unqualified_lookup::some_union{0};
assert(std::ranges::iter_move(some_union) == 0);
assert(!noexcept(std::ranges::iter_move(some_union)));
static_assert(!noexcept(std::ranges::iter_move(some_union)));

// Check noexcept-correctness
static_assert(noexcept(std::ranges::iter_move(std::declval<WithADL<true>>())));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ using ElementsIter = std::ranges::iterator_t<std::ranges::elements_view<BaseView
static_assert(IsBaseNoexcept<const ElementsIter&>);
static_assert(IsBaseNoexcept<ElementsIter&>);
static_assert(IsBaseNoexcept<const ElementsIter&&>);
static_assert(!IsBaseNoexcept<ElementsIter&&>);
LIBCPP_STATIC_ASSERT(!IsBaseNoexcept<ElementsIter&&>);

constexpr bool test() {
std::tuple<int> t{5};
Expand Down