[libcxx-commits] [libcxx] fbcd523 - [libc++] [ranges] Fix `decltype(auto) ranges::iter_move`.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Mon Mar 7 10:31:25 PST 2022


Author: Arthur O'Dwyer
Date: 2022-03-07T13:31:16-05:00
New Revision: fbcd5236af20e7d1373f5d88e0a9b49e34614fdc

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

LOG: [libc++] [ranges] Fix `decltype(auto) ranges::iter_move`.

See
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92894#c3
https://reviews.llvm.org/D119589#inline-1151299

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

Added: 
    libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp

Modified: 
    libcxx/include/__iterator/iter_move.h

Removed: 
    libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp


################################################################################
diff  --git a/libcxx/include/__iterator/iter_move.h b/libcxx/include/__iterator/iter_move.h
index 97d54c4a825cf..66d69af7fd841 100644
--- a/libcxx/include/__iterator/iter_move.h
+++ b/libcxx/include/__iterator/iter_move.h
@@ -39,6 +39,23 @@ concept __unqualified_iter_move =
     iter_move(std::forward<_Tp>(__t));
   };
 
+template<class _Tp>
+concept __move_deref =
+  !__unqualified_iter_move<_Tp> &&
+  requires (_Tp&& __t) {
+    *__t;
+    requires is_lvalue_reference_v<decltype(*__t)>;
+  };
+
+template<class _Tp>
+concept __just_deref =
+  !__unqualified_iter_move<_Tp> &&
+  !__move_deref<_Tp> &&
+  requires (_Tp&& __t) {
+    *__t;
+    requires (!is_lvalue_reference_v<decltype(*__t)>);
+  };
+
 // [iterator.cust.move]
 
 struct __fn {
@@ -51,17 +68,18 @@ struct __fn {
   }
 
   template<class _Ip>
-    requires (!__unqualified_iter_move<_Ip>) &&
-             requires { *declval<_Ip>(); }
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator()(_Ip&& __i) const
+    requires __move_deref<_Ip>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const
+    noexcept(noexcept(std::move(*std::forward<_Ip>(__i))))
+    -> decltype(      std::move(*std::forward<_Ip>(__i)))
+    { return          std::move(*std::forward<_Ip>(__i)); }
+
+  template<class _Ip>
+    requires __just_deref<_Ip>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Ip&& __i) const
     noexcept(noexcept(*std::forward<_Ip>(__i)))
-  {
-    if constexpr (is_lvalue_reference_v<decltype(*declval<_Ip>())>) {
-      return std::move(*std::forward<_Ip>(__i));
-    } else {
-      return *std::forward<_Ip>(__i);
-    }
-  }
+    -> decltype(      *std::forward<_Ip>(__i))
+    { return          *std::forward<_Ip>(__i); }
 };
 } // namespace __iter_move
 

diff  --git a/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp b/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
similarity index 57%
rename from libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp
rename to libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
index 6c19ec3ae33af..441b3caca02db 100644
--- a/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp
+++ b/libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
@@ -14,12 +14,12 @@
 
 #include <iterator>
 
-#include <concepts>
-#include <list>
-#include <vector>
+static_assert(std::same_as<std::iter_rvalue_reference_t<int*>, int&&>);
+static_assert(std::same_as<std::iter_rvalue_reference_t<const int*>, const int&&>);
 
-static_assert(std::same_as<std::iter_rvalue_reference_t<std::vector<int>::iterator&>, int&&>);
-static_assert(std::same_as<std::iter_rvalue_reference_t<std::vector<int>::const_iterator>, int const&&>);
-static_assert(std::same_as<std::iter_rvalue_reference_t<std::list<int const>::iterator>, int const&&>);
-
-int main(int, char**) { return 0; }
+void test_undefined_internal() {
+  struct A {
+    int& operator*() const;
+  };
+  static_assert(std::same_as<std::iter_rvalue_reference_t<A>, int&&>);
+}


        


More information about the libcxx-commits mailing list