diff --git a/libcxx/include/__ranges/empty.h b/libcxx/include/__ranges/empty.h --- a/libcxx/include/__ranges/empty.h +++ b/libcxx/include/__ranges/empty.h @@ -41,6 +41,7 @@ template concept __can_compare_begin_end = + !__member_empty<_Tp> && !__can_invoke_size<_Tp> && requires(_Tp&& __t) { bool(ranges::begin(__t) == ranges::end(__t)); diff --git a/libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp b/libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp --- a/libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp +++ b/libcxx/test/std/ranges/range.access/range.prim/empty.pass.cpp @@ -133,6 +133,18 @@ inline constexpr bool std::disable_sized_range = true; static_assert(!std::is_invocable_v); +struct BeginEndAndEmpty { + int* begin(); + int* end(); + constexpr bool empty() { return true; } +}; + +struct BeginEndAndConstEmpty { + int* begin(); + int* end(); + constexpr bool empty() const { return true; } +}; + constexpr bool testBeginEqualsEnd() { BeginEndNotSizedSentinel a; assert(std::ranges::empty(a) == true); @@ -146,6 +158,13 @@ DisabledSizeRangeWithBeginEnd d; assert(std::ranges::empty(d) == true); + BeginEndAndEmpty e; + assert(std::ranges::empty(e) == true); + + BeginEndAndConstEmpty f; + assert(std::ranges::empty(f) == true); + assert(std::ranges::empty(std::as_const(f)) == true); + return true; }