[libc++][ranges] Finish LWG issues directly related to the One Ranges Proposal.

- P1252 ("Ranges Design Cleanup") -- deprecate
  `move_iterator::operator->` starting from C++20; add range comparisons
  to the `<functional>` synopsis. This restores
  `move_iterator::operator->` that was incorrectly deleted in D117656;
  it's still defined in the latest draft, see
  http://eel.is/c++draft/depr.move.iter.elem. Note that changes to
  `*_result` types from 6.1 in the paper are no longer relevant now that
  these types are aliases;
- P2106 ("Alternative wording for GB315 and GB316") -- add a few
  `*_result` types to the synopsis in `<algorithm>` (some algorithms are
  not implemented yet and thus some of the proposal still cannot be
  marked as done);

Also mark already done issues as done (or as nothing to do):
- P2091 ("Fixing Issues With Range Access CPOs") was already implemented
  (this patch adds tests for some ill-formed cases);
- LWG 3247 ("`ranges::iter_move` should perform ADL-only lookup of
  `iter_move`") was already implemented;
- LWG 3300 ("Non-array ssize overload is underconstrained") doesn't
  affect the implementation;
- LWG 3335 ("Resolve C++20 NB comments US 273 and GB 274") was already
  implemented;
- LWG 3355 ("The memory algorithms should support move-only input
  iterators introduced by P1207") was already implemented (except for
  testing).

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

NOKEYCHECK=True
GitOrigin-RevId: 79a2b4ba98a1eecc214b68fc31483ebbd7cf8c8a
diff --git a/include/__iterator/move_iterator.h b/include/__iterator/move_iterator.h
index e0c7e73..6be9f21 100644
--- a/include/__iterator/move_iterator.h
+++ b/include/__iterator/move_iterator.h
@@ -93,6 +93,9 @@
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
     move_iterator& operator++() { ++__current_; return *this; }
 
+    _LIBCPP_DEPRECATED_IN_CXX20 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
+    pointer operator->() const { return __current_; }
+
 #if _LIBCPP_STD_VER > 17
     _LIBCPP_HIDE_FROM_ABI constexpr
     move_iterator() requires is_constructible_v<_Iter> : __current_() {}
@@ -156,8 +159,6 @@
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
     reference operator*() const { return static_cast<reference>(*__current_); }
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
-    pointer operator->() const { return __current_; }
-    _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
     reference operator[](difference_type __n) const { return static_cast<reference>(__current_[__n]); }
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
diff --git a/include/__ranges/size.h b/include/__ranges/size.h
index b832668..32ca4b8 100644
--- a/include/__ranges/size.h
+++ b/include/__ranges/size.h
@@ -35,68 +35,76 @@
 
 namespace ranges {
 namespace __size {
-  void size(auto&) = delete;
-  void size(const auto&) = delete;
+void size(auto&) = delete;
+void size(const auto&) = delete;
 
-  template <class _Tp>
-  concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>;
+template <class _Tp>
+concept __size_enabled = !disable_sized_range<remove_cvref_t<_Tp>>;
 
-  template <class _Tp>
-  concept __member_size =
-    __size_enabled<_Tp> &&
-    __workaround_52970<_Tp> &&
-    requires(_Tp&& __t) {
-      { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like;
-    };
-
-  template <class _Tp>
-  concept __unqualified_size =
-    __size_enabled<_Tp> &&
-    !__member_size<_Tp> &&
-    __class_or_enum<remove_cvref_t<_Tp>> &&
-    requires(_Tp&& __t) {
-      { _LIBCPP_AUTO_CAST(size(__t)) } -> __integer_like;
-    };
-
-  template <class _Tp>
-  concept __difference =
-    !__member_size<_Tp> &&
-    !__unqualified_size<_Tp> &&
-    __class_or_enum<remove_cvref_t<_Tp>> &&
-    requires(_Tp&& __t) {
-      { ranges::begin(__t) } -> forward_iterator;
-      { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(declval<_Tp>()))>;
-    };
-
-  struct __fn {
-    template <class _Tp, size_t _Sz>
-    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
-      return _Sz;
-    }
-
-    template <class _Tp, size_t _Sz>
-    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {
-      return _Sz;
-    }
-
-    template <__member_size _Tp>
-    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
-        noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.size()))) {
-      return _LIBCPP_AUTO_CAST(__t.size());
-    }
-
-    template <__unqualified_size _Tp>
-    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
-        noexcept(noexcept(_LIBCPP_AUTO_CAST(size(__t)))) {
-      return _LIBCPP_AUTO_CAST(size(__t));
-    }
-
-    template<__difference _Tp>
-    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
-        noexcept(noexcept(ranges::end(__t) - ranges::begin(__t))) {
-      return std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
-    }
+template <class _Tp>
+concept __member_size =
+  __size_enabled<_Tp> &&
+  __workaround_52970<_Tp> &&
+  requires(_Tp&& __t) {
+    { _LIBCPP_AUTO_CAST(__t.size()) } -> __integer_like;
   };
+
+template <class _Tp>
+concept __unqualified_size =
+  __size_enabled<_Tp> &&
+  !__member_size<_Tp> &&
+  __class_or_enum<remove_cvref_t<_Tp>> &&
+  requires(_Tp&& __t) {
+    { _LIBCPP_AUTO_CAST(size(__t)) } -> __integer_like;
+  };
+
+template <class _Tp>
+concept __difference =
+  !__member_size<_Tp> &&
+  !__unqualified_size<_Tp> &&
+  __class_or_enum<remove_cvref_t<_Tp>> &&
+  requires(_Tp&& __t) {
+    { ranges::begin(__t) } -> forward_iterator;
+    { ranges::end(__t) } -> sized_sentinel_for<decltype(ranges::begin(declval<_Tp>()))>;
+  };
+
+struct __fn {
+
+  // `[range.prim.size]`: the array case (for rvalues).
+  template <class _Tp, size_t _Sz>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&&)[_Sz]) const noexcept {
+    return _Sz;
+  }
+
+  // `[range.prim.size]`: the array case (for lvalues).
+  template <class _Tp, size_t _Sz>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_t operator()(_Tp (&)[_Sz]) const noexcept {
+    return _Sz;
+  }
+
+  // `[range.prim.size]`: `auto(t.size())` is a valid expression.
+  template <__member_size _Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+      noexcept(noexcept(_LIBCPP_AUTO_CAST(__t.size()))) {
+    return _LIBCPP_AUTO_CAST(__t.size());
+  }
+
+  // `[range.prim.size]`: `auto(size(t))` is a valid expression.
+  template <__unqualified_size _Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr __integer_like auto operator()(_Tp&& __t) const
+      noexcept(noexcept(_LIBCPP_AUTO_CAST(size(__t)))) {
+    return _LIBCPP_AUTO_CAST(size(__t));
+  }
+
+  // [range.prim.size]: the `to-unsigned-like` case.
+  template <__difference _Tp>
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Tp&& __t) const
+    noexcept(noexcept(std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t))))
+    -> decltype(      std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t)))
+    { return          std::__to_unsigned_like(ranges::end(__t) - ranges::begin(__t));
+  }
+};
+
 } // namespace __size
 
 inline namespace __cpo {
@@ -108,19 +116,18 @@
 
 namespace ranges {
 namespace __ssize {
-  struct __fn {
-    template<class _Tp>
-      requires requires (_Tp&& __t) { ranges::size(__t); }
-    [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const
-      noexcept(noexcept(ranges::size(__t)))
-    {
-      using _Signed = make_signed_t<decltype(ranges::size(__t))>;
-      if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed))
-        return static_cast<ptrdiff_t>(ranges::size(__t));
-      else
-        return static_cast<_Signed>(ranges::size(__t));
-    }
-  };
+struct __fn {
+  template<class _Tp>
+    requires requires (_Tp&& __t) { ranges::size(__t); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr integral auto operator()(_Tp&& __t) const
+    noexcept(noexcept(ranges::size(__t))) {
+    using _Signed = make_signed_t<decltype(ranges::size(__t))>;
+    if constexpr (sizeof(ptrdiff_t) > sizeof(_Signed))
+      return static_cast<ptrdiff_t>(ranges::size(__t));
+    else
+      return static_cast<_Signed>(ranges::size(__t));
+  }
+};
 } // namespace __ssize
 
 inline namespace __cpo {
diff --git a/include/algorithm b/include/algorithm
index 9ae6471..62b67c3 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -19,12 +19,17 @@
 {
 
 namespace ranges {
+
+  // [algorithms.results], algorithm result types
   template <class I, class F>
     struct in_fun_result;     // since C++20
 
   template <class I1, class I2>
     struct in_in_result;      // since C++20
 
+  template <class I, class O>
+    struct in_out_result;  // since C++20
+
   template <class I1, class I2, class O>
     struct in_in_out_result;  // since C++20
 
@@ -53,6 +58,9 @@
     indirect_strict_weak_order<projected<iterator_t<R>, Proj>> Comp = ranges::less>
   constexpr borrowed_iterator_t<R> ranges::max_element(R&& r, Comp comp = {}, Proj proj = {});             // since C++20
 
+  template<class I1, class I2>
+    using mismatch_result = in_in_result<I1, I2>;
+
   template <input_iterator I1, sentinel_for<_I1> S1, input_iterator I2, sentinel_for<_I2> S2,
           class Pred = ranges::equal_to, class Proj1 = identity, class Proj2 = identity>
     requires indirectly_comparable<I1, I2, Pred, Proj1, Proj2>
@@ -174,6 +182,9 @@
     constexpr range_difference_t<R>
       count_if(R&& r, Pred pred, Proj proj = {});                                   // since C++20
 
+  template<class T>
+  using minmax_result = min_max_result<T>;
+
   template<class T, class Proj = identity,
            indirect_strict_weak_order<projected<const T*, Proj>> Comp = ranges::less>
     constexpr ranges::minmax_result<const T&>
@@ -190,6 +201,9 @@
     constexpr ranges::minmax_result<range_value_t<R>>
       minmax(R&& r, Comp comp = {}, Proj proj = {});                                      // since C++20
 
+  template<class I>
+  using minmax_element_result = min_max_result<I>;
+
   template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
            indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
     constexpr ranges::minmax_element_result<I>
@@ -201,10 +215,10 @@
       minmax_element(R&& r, Comp comp = {}, Proj proj = {});                              // since C++20
 
   template<class I, class O>
-      using copy_result = in_out_result<I, O>;                                              // since C++20
+    using copy_result = in_out_result<I, O>;                                              // since C++20
 
-    template<class I, class O>
-      using copy_n_result = in_out_result<I, O>;                                            // since C++20
+  template<class I, class O>
+    using copy_n_result = in_out_result<I, O>;                                            // since C++20
 
   template<class I, class O>
     using copy_if_result = in_out_result<I, O>;                                             // since C++20
@@ -638,19 +652,34 @@
     copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
                   BidirectionalIterator2 result);
 
+// [alg.move], move
+template<class InputIterator, class OutputIterator>
+    constexpr OutputIterator move(InputIterator first, InputIterator last,
+                                OutputIterator result);
+
+template<class BidirectionalIterator1, class BidirectionalIterator2>
+    constexpr BidirectionalIterator2
+    move_backward(BidirectionalIterator1 first, BidirectionalIterator1 last,
+                  BidirectionalIterator2 result);
+
 template <class ForwardIterator1, class ForwardIterator2>
     constexpr ForwardIterator2    // constexpr in C++20
     swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);
 
+namespace ranges {
+    template<class I1, class I2>
+    using swap_ranges_result = in_in_result<I1, I2>;
+
 template<input_iterator I1, sentinel_for<I1> S1, input_iterator I2, sentinel_for<I2> S2>
         requires indirectly_swappable<I1, I2>
     constexpr ranges::swap_ranges_result<I1, I2>
-        ranges::swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2);
+        swap_ranges(I1 first1, S1 last1, I2 first2, S2 last2);
 
 template<input_range R1, input_range R2>
         requires indirectly_swappable<iterator_t<R1>, iterator_t<R2>>
     constexpr ranges::swap_ranges_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
-        ranges::swap_ranges(R1&& r1, R2&& r2);
+        swap_ranges(R1&& r1, R2&& r2);
+}
 
 template <class ForwardIterator1, class ForwardIterator2>
     constexpr void                // constexpr in C++20
diff --git a/include/functional b/include/functional
index ca17dd4..de02059 100644
--- a/include/functional
+++ b/include/functional
@@ -482,6 +482,16 @@
 template<class T> struct hash<T*>;
 template <> struct hash<nullptr_t>;  // C++17
 
+namespace ranges {
+  // [range.cmp], concept-constrained comparisons
+  struct equal_to;
+  struct not_equal_to;
+  struct greater;
+  struct less;
+  struct greater_equal;
+  struct less_equal;
+}
+
 }  // std
 
 POLICY:  For non-variadic implementations, the number of arguments is limited
diff --git a/include/iterator b/include/iterator
index d2f5ac2..225ae81 100644
--- a/include/iterator
+++ b/include/iterator
@@ -406,7 +406,7 @@
     constexpr Iterator base() &&; // From C++20
 
     constexpr reference operator*() const;
-    constexpr pointer operator->() const; // Removed in C++20
+    constexpr pointer operator->() const; // Deprecated in C++20
     constexpr move_iterator& operator++();
     constexpr auto operator++(int); // Return type was move_iterator until C++20
     constexpr move_iterator& operator--();