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

Arthur O'Dwyer via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Wed Mar 2 14:53:41 PST 2022


Quuxplusone updated this revision to Diff 412551.
Quuxplusone retitled this revision from "[libc++] [ranges] Regression test for decltype(auto) ranges::iter_move" to "[libc++] [ranges] Fix `decltype(auto) ranges::iter_move`".
Quuxplusone edited the summary of this revision.
Quuxplusone added a comment.
Herald added a project: All.

I finally hit a reproducing case locally, while writing tests for C++20 `move_iterator`!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D120417/new/

https://reviews.llvm.org/D120417

Files:
  libcxx/include/__iterator/iter_move.h
  libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
  libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.pass.cpp


Index: libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
===================================================================
--- libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
+++ libcxx/test/std/iterators/iterator.requirements/iterator.cust/iterator.cust.move/iter_rvalue_reference_t.compile.pass.cpp
@@ -14,12 +14,14 @@
 
 #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 {
+    using value_type = int;
+    using difference_type = int;
+    int& operator*() const;
+  };
+  static_assert(std::same_as<std::iter_rvalue_reference_t<A>, int&&>);
+}
Index: libcxx/include/__iterator/iter_move.h
===================================================================
--- libcxx/include/__iterator/iter_move.h
+++ libcxx/include/__iterator/iter_move.h
@@ -39,6 +39,23 @@
     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 @@
   }
 
   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
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D120417.412551.patch
Type: text/x-patch
Size: 3011 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20220302/599d783e/attachment-0001.bin>


More information about the libcxx-commits mailing list