diff --git a/libcxx/include/__ranges/access.h b/libcxx/include/__ranges/access.h --- a/libcxx/include/__ranges/access.h +++ b/libcxx/include/__ranges/access.h @@ -168,7 +168,7 @@ } template - requires is_rvalue_reference_v<_Tp> && invocable + requires is_rvalue_reference_v<_Tp&&> && invocable [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(ranges::begin(static_cast<_Tp const&&>(__t)))) { @@ -196,7 +196,7 @@ } template - requires is_rvalue_reference_v<_Tp> && invocable + requires is_rvalue_reference_v<_Tp&&> && invocable [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const noexcept(noexcept(ranges::end(static_cast<_Tp const&&>(__t)))) { diff --git a/libcxx/test/std/ranges/range.access/begin.pass.cpp b/libcxx/test/std/ranges/range.access/begin.pass.cpp --- a/libcxx/test/std/ranges/range.access/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.access/begin.pass.cpp @@ -11,6 +11,7 @@ // UNSUPPORTED: libcpp-has-no-incomplete-ranges // std::ranges::begin +// std::ranges::cbegin #include @@ -18,8 +19,8 @@ #include "test_macros.h" #include "test_iterators.h" -using RangeBeginT = decltype(std::ranges::begin)&; -using RangeCBeginT = decltype(std::ranges::cbegin)&; +using RangeBeginT = decltype(std::ranges::begin); +using RangeCBeginT = decltype(std::ranges::cbegin); static int globalBuff[8]; @@ -118,12 +119,18 @@ BeginMember a; assert(std::ranges::begin(a) == &a.x); assert(std::ranges::cbegin(a) == &a.x); + static_assert(!std::is_invocable_v); + static_assert(!std::is_invocable_v); NonConstBeginMember b; assert(std::ranges::begin(b) == &b.x); + static_assert(!std::is_invocable_v); EnabledBorrowingBeginMember c; + assert(std::ranges::begin(c) == &globalBuff[0]); + assert(std::ranges::cbegin(c) == &globalBuff[0]); assert(std::ranges::begin(std::move(c)) == &globalBuff[0]); + assert(std::ranges::cbegin(std::move(c)) == &globalBuff[0]); BeginMemberFunction d; assert(std::ranges::begin(d) == &d.x); @@ -202,44 +209,44 @@ constexpr bool testBeginFunction() { BeginFunction a{}; const BeginFunction aa{}; - static_assert(!std::invocable); - assert(std::ranges::begin(aa) == &aa.x); + static_assert(!std::invocable); assert(std::ranges::cbegin(a) == &a.x); + assert(std::ranges::begin(aa) == &aa.x); assert(std::ranges::cbegin(aa) == &aa.x); BeginFunctionByValue b{}; const BeginFunctionByValue bb{}; assert(std::ranges::begin(b) == &globalBuff[1]); - assert(std::ranges::begin(bb) == &globalBuff[1]); assert(std::ranges::cbegin(b) == &globalBuff[1]); + assert(std::ranges::begin(bb) == &globalBuff[1]); assert(std::ranges::cbegin(bb) == &globalBuff[1]); BeginFunctionEnabledBorrowing c{}; const BeginFunctionEnabledBorrowing cc{}; assert(std::ranges::begin(std::move(c)) == &globalBuff[2]); - static_assert(!std::invocable); + assert(std::ranges::cbegin(std::move(c)) == &globalBuff[2]); assert(std::ranges::begin(std::move(cc)) == &globalBuff[2]); assert(std::ranges::cbegin(std::move(cc)) == &globalBuff[2]); BeginFunctionReturnsEmptyPtr d{}; const BeginFunctionReturnsEmptyPtr dd{}; - static_assert(!std::invocable); - assert(std::ranges::begin(dd) == &dd.x); + static_assert(!std::invocable); assert(std::ranges::cbegin(d) == &d.x); + assert(std::ranges::begin(dd) == &dd.x); assert(std::ranges::cbegin(dd) == &dd.x); BeginFunctionWithDataMember e{}; const BeginFunctionWithDataMember ee{}; - static_assert(!std::invocable); + static_assert(!std::invocable); assert(std::ranges::begin(ee) == &ee.x); assert(std::ranges::cbegin(e) == &e.x); assert(std::ranges::cbegin(ee) == &ee.x); BeginFunctionWithPrivateBeginMember f{}; const BeginFunctionWithPrivateBeginMember ff{}; - static_assert(!std::invocable); - assert(std::ranges::begin(ff) == &ff.y); + static_assert(!std::invocable); assert(std::ranges::cbegin(f) == &f.y); + assert(std::ranges::begin(ff) == &ff.y); assert(std::ranges::cbegin(ff) == &ff.y); return true; @@ -274,7 +281,6 @@ static_assert(noexcept(std::ranges::begin(brar))); static_assert(noexcept(std::ranges::cbegin(brar))); - int main(int, char**) { testArray(); static_assert(testArray()); diff --git a/libcxx/test/std/ranges/range.access/end.pass.cpp b/libcxx/test/std/ranges/range.access/end.pass.cpp --- a/libcxx/test/std/ranges/range.access/end.pass.cpp +++ b/libcxx/test/std/ranges/range.access/end.pass.cpp @@ -11,6 +11,7 @@ // UNSUPPORTED: libcpp-has-no-incomplete-ranges // std::ranges::end +// std::ranges::cend #include @@ -18,8 +19,8 @@ #include "test_macros.h" #include "test_iterators.h" -using RangeEndT = decltype(std::ranges::end)&; -using RangeCEndT = decltype(std::ranges::cend)&; +using RangeEndT = decltype(std::ranges::end); +using RangeCEndT = decltype(std::ranges::cend); static int globalBuff[8]; @@ -139,9 +140,11 @@ NonConstEndMember b; assert(std::ranges::end(b) == &b.x); + static_assert(!std::is_invocable_v); EnabledBorrowingEndMember c; assert(std::ranges::end(std::move(c)) == &globalBuff[0]); + assert(std::ranges::cend(std::move(c)) == &globalBuff[0]); EndMemberFunction d; assert(std::ranges::end(d) == &d.x); @@ -246,7 +249,9 @@ constexpr bool testEndFunction() { const EndFunction a{}; assert(std::ranges::end(a) == &a.x); + assert(std::ranges::cend(a) == &a.x); EndFunction aa{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(aa) == &aa.x); EndFunctionByValue b; @@ -255,25 +260,34 @@ EndFunctionEnabledBorrowing c; assert(std::ranges::end(std::move(c)) == &globalBuff[2]); + assert(std::ranges::cend(std::move(c)) == &globalBuff[2]); const EndFunctionReturnsEmptyPtr d{}; assert(std::ranges::end(d) == &d.x); + assert(std::ranges::cend(d) == &d.x); EndFunctionReturnsEmptyPtr dd{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(dd) == &dd.x); const EndFunctionWithDataMember e{}; assert(std::ranges::end(e) == &e.x); + assert(std::ranges::cend(e) == &e.x); EndFunctionWithDataMember ee{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(ee) == &ee.x); const EndFunctionWithPrivateEndMember f{}; assert(std::ranges::end(f) == &f.y); + assert(std::ranges::cend(f) == &f.y); EndFunctionWithPrivateEndMember ff{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(ff) == &ff.y); const BeginMemberEndFunction g{}; assert(std::ranges::end(g) == &g.x); + assert(std::ranges::cend(g) == &g.x); BeginMemberEndFunction gg{}; + static_assert(!std::is_invocable_v); assert(std::ranges::cend(gg) == &gg.x); return true;