[libcxx-commits] [libcxx] a70fe03 - [libc++] [ranges] SFINAE away ranges::cbegin(const T&&) for non-borrowed T.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jan 12 10:26:00 PST 2022


Author: Arthur O'Dwyer
Date: 2022-01-12T13:25:41-05:00
New Revision: a70fe03961ddb483607861a79ce569a24757919f

URL: https://github.com/llvm/llvm-project/commit/a70fe03961ddb483607861a79ce569a24757919f
DIFF: https://github.com/llvm/llvm-project/commit/a70fe03961ddb483607861a79ce569a24757919f.diff

LOG: [libc++] [ranges] SFINAE away ranges::cbegin(const T&&) for non-borrowed T.

Fixes #52952.

Differential Revision: https://reviews.llvm.org/D116991

Added: 
    

Modified: 
    libcxx/include/__ranges/access.h
    libcxx/test/std/ranges/range.access/begin.pass.cpp
    libcxx/test/std/ranges/range.access/end.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__ranges/access.h b/libcxx/include/__ranges/access.h
index 246f8b20caf43..0b9470fa4017e 100644
--- a/libcxx/include/__ranges/access.h
+++ b/libcxx/include/__ranges/access.h
@@ -163,11 +163,12 @@ namespace ranges {
 namespace __cbegin {
   struct __fn {
     template <class _Tp>
+      requires is_lvalue_reference_v<_Tp&&>
     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
-    constexpr auto operator()(_Tp& __t) const
-      noexcept(noexcept(ranges::begin(static_cast<const _Tp&>(__t))))
-      -> decltype(      ranges::begin(static_cast<const _Tp&>(__t)))
-      { return          ranges::begin(static_cast<const _Tp&>(__t)); }
+    constexpr auto operator()(_Tp&& __t) const
+      noexcept(noexcept(ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t))))
+      -> decltype(      ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)))
+      { return          ranges::begin(static_cast<const remove_reference_t<_Tp>&>(__t)); }
 
     template <class _Tp>
       requires is_rvalue_reference_v<_Tp&&>
@@ -190,11 +191,12 @@ namespace ranges {
 namespace __cend {
   struct __fn {
     template <class _Tp>
+      requires is_lvalue_reference_v<_Tp&&>
     [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
-    constexpr auto operator()(_Tp& __t) const
-      noexcept(noexcept(ranges::end(static_cast<const _Tp&>(__t))))
-      -> decltype(      ranges::end(static_cast<const _Tp&>(__t)))
-      { return          ranges::end(static_cast<const _Tp&>(__t)); }
+    constexpr auto operator()(_Tp&& __t) const
+      noexcept(noexcept(ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t))))
+      -> decltype(      ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)))
+      { return          ranges::end(static_cast<const remove_reference_t<_Tp>&>(__t)); }
 
     template <class _Tp>
       requires is_rvalue_reference_v<_Tp&&>

diff  --git a/libcxx/test/std/ranges/range.access/begin.pass.cpp b/libcxx/test/std/ranges/range.access/begin.pass.cpp
index 11170fa4f9943..36741f16823e1 100644
--- a/libcxx/test/std/ranges/range.access/begin.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/begin.pass.cpp
@@ -48,7 +48,7 @@ static_assert(!std::is_invocable_v<RangeBeginT, BeginMember const&&>);
 static_assert( std::is_invocable_v<RangeCBeginT, BeginMember &>);
 static_assert(!std::is_invocable_v<RangeCBeginT, BeginMember &&>);
 static_assert( std::is_invocable_v<RangeCBeginT, BeginMember const&>);
-static_assert( std::is_invocable_v<RangeCBeginT, BeginMember const&&>);
+static_assert(!std::is_invocable_v<RangeCBeginT, BeginMember const&&>);
 
 constexpr bool testReturnTypes() {
   {

diff  --git a/libcxx/test/std/ranges/range.access/end.pass.cpp b/libcxx/test/std/ranges/range.access/end.pass.cpp
index 4b1d4e3f488d0..9d10d0aa4aed4 100644
--- a/libcxx/test/std/ranges/range.access/end.pass.cpp
+++ b/libcxx/test/std/ranges/range.access/end.pass.cpp
@@ -37,16 +37,19 @@ static_assert(!std::is_invocable_v<RangeCEndT, Incomplete(&&)[42]>);
 
 struct EndMember {
   int x;
-  constexpr const int *begin() const { return nullptr; }
+  const int *begin() const;
   constexpr const int *end() const { return &x; }
 };
 
 // Ensure that we can't call with rvalues with borrowing disabled.
-static_assert( std::is_invocable_v<RangeEndT,  EndMember &>);
-static_assert( std::is_invocable_v<RangeEndT,  EndMember const&>);
-static_assert(!std::is_invocable_v<RangeEndT,  EndMember &&>);
+static_assert( std::is_invocable_v<RangeEndT, EndMember &>);
+static_assert(!std::is_invocable_v<RangeEndT, EndMember &&>);
+static_assert( std::is_invocable_v<RangeEndT, EndMember const&>);
+static_assert(!std::is_invocable_v<RangeEndT, EndMember const&&>);
 static_assert( std::is_invocable_v<RangeCEndT, EndMember &>);
+static_assert(!std::is_invocable_v<RangeCEndT, EndMember &&>);
 static_assert( std::is_invocable_v<RangeCEndT, EndMember const&>);
+static_assert(!std::is_invocable_v<RangeCEndT, EndMember const&&>);
 
 constexpr bool testReturnTypes() {
   {


        


More information about the libcxx-commits mailing list