libstdc++: Fix noexcept-specifier for ranges::empty

Signed-off-by: Jonathan Wakely <jwakely@redhat.com>

libstdc++-v3/ChangeLog:

	* include/bits/ranges_base.h (ranges::empty): Check whether
	conversion to bool can throw.
	* testsuite/std/ranges/access/empty.cc: Check for correct
	noexcept-specifier.
This commit is contained in:
Jonathan Wakely 2021-06-14 22:42:05 +01:00
parent 20073534c0
commit f9598d89a9
2 changed files with 32 additions and 1 deletions

View file

@ -476,7 +476,7 @@ namespace ranges
_S_noexcept()
{
if constexpr (__member_empty<_Tp>)
return noexcept(std::declval<_Tp&>().empty());
return noexcept(bool(std::declval<_Tp&>().empty()));
else if constexpr (__size0_empty<_Tp>)
return noexcept(_Size{}(std::declval<_Tp&>()) == 0);
else

View file

@ -89,10 +89,41 @@ test03()
static_assert( std::ranges::empty(R2{}) );
}
void
test04()
{
struct E1
{
bool empty() const noexcept { return {}; }
};
static_assert( noexcept(std::ranges::empty(E1{})) );
struct E2
{
bool empty() const noexcept(false) { return {}; }
};
static_assert( ! noexcept(std::ranges::empty(E2{})) );
struct E3
{
struct B
{
explicit operator bool() const noexcept(false) { return true; }
};
B empty() const noexcept { return {}; }
};
static_assert( ! noexcept(std::ranges::empty(E3{})) );
}
int
main()
{
test01();
test02();
test03();
test04();
}