diff --git a/libcxx/include/__algorithm/adjacent_find.h b/libcxx/include/__algorithm/adjacent_find.h
index 2508250d8796c..89cdc8fa0ae94 100644
--- a/libcxx/include/__algorithm/adjacent_find.h
+++ b/libcxx/include/__algorithm/adjacent_find.h
@@ -27,7 +27,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Iter, class _Sent, class _Pred, class _Proj>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Iter
-__adjacent_find(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+__adjacent_find(_Iter __first, _Sent __last, _Pred&& __pred, _Proj&& __proj) {
   if (__first == __last)
     return __first;
 
diff --git a/libcxx/include/__algorithm/all_of.h b/libcxx/include/__algorithm/all_of.h
index 6acc117fc47bc..a2efff1296445 100644
--- a/libcxx/include/__algorithm/all_of.h
+++ b/libcxx/include/__algorithm/all_of.h
@@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Iter, class _Sent, class _Proj, class _Pred>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
-__all_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+__all_of(_Iter __first, _Sent __last, _Pred&& __pred, _Proj&& __proj) {
   for (; __first != __last; ++__first) {
     if (!std::__invoke(__pred, std::__invoke(__proj, *__first)))
       return false;
diff --git a/libcxx/include/__algorithm/any_of.h b/libcxx/include/__algorithm/any_of.h
index 4b6eb94517286..15b82754977d4 100644
--- a/libcxx/include/__algorithm/any_of.h
+++ b/libcxx/include/__algorithm/any_of.h
@@ -22,7 +22,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Iter, class _Sent, class _Proj, class _Pred>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 bool
-__any_of(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+__any_of(_Iter __first, _Sent __last, _Pred&& __pred, _Proj&& __proj) {
   for (; __first != __last; ++__first) {
     if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
       return true;
diff --git a/libcxx/include/__algorithm/copy_if.h b/libcxx/include/__algorithm/copy_if.h
index ffea621fc0618..d4b5ba99d4658 100644
--- a/libcxx/include/__algorithm/copy_if.h
+++ b/libcxx/include/__algorithm/copy_if.h
@@ -26,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_InIter, _OutIter>
-__copy_if(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
+__copy_if(_InIter __first, _Sent __last, _OutIter __result, _Pred&& __pred, _Proj&& __proj) {
   for (; __first != __last; ++__first) {
     if (std::__invoke(__pred, std::__invoke(__proj, *__first))) {
       *__result = *__first;
diff --git a/libcxx/include/__algorithm/count.h b/libcxx/include/__algorithm/count.h
index 0cbe9b6e61b98..5bbb9e36d4225 100644
--- a/libcxx/include/__algorithm/count.h
+++ b/libcxx/include/__algorithm/count.h
@@ -33,7 +33,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // generic implementation
 template <class _AlgPolicy, class _Iter, class _Sent, class _Tp, class _Proj>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 typename _IterOps<_AlgPolicy>::template __difference_type<_Iter>
-__count(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
+__count(_Iter __first, _Sent __last, const _Tp& __value, _Proj&& __proj) {
   typename _IterOps<_AlgPolicy>::template __difference_type<_Iter> __r(0);
   for (; __first != __last; ++__first)
     if (std::__invoke(__proj, *__first) == __value)
diff --git a/libcxx/include/__algorithm/count_if.h b/libcxx/include/__algorithm/count_if.h
index 26f945e6bd98c..a905ad0f9b516 100644
--- a/libcxx/include/__algorithm/count_if.h
+++ b/libcxx/include/__algorithm/count_if.h
@@ -24,7 +24,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy, class _Iter, class _Sent, class _Proj, class _Pred>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 __policy_iter_diff_t<_AlgPolicy, _Iter>
-__count_if(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+__count_if(_Iter __first, _Sent __last, _Pred&& __pred, _Proj&& __proj) {
   __policy_iter_diff_t<_AlgPolicy, _Iter> __counter(0);
   for (; __first != __last; ++__first) {
     if (std::__invoke(__pred, std::__invoke(__proj, *__first)))
diff --git a/libcxx/include/__algorithm/equal.h b/libcxx/include/__algorithm/equal.h
index 5a8c9504ede1d..8b922c1b4a8db 100644
--- a/libcxx/include/__algorithm/equal.h
+++ b/libcxx/include/__algorithm/equal.h
@@ -208,7 +208,13 @@ equal(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __first
 
 template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __equal_impl(
-    _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __comp, _Proj1& __proj1, _Proj2& __proj2) {
+    _Iter1 __first1,
+    _Sent1 __last1,
+    _Iter2 __first2,
+    _Sent2 __last2,
+    _Pred&& __comp,
+    _Proj1&& __proj1,
+    _Proj2&& __proj2) {
   while (__first1 != __last1 && __first2 != __last2) {
     if (!std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
       return false;
@@ -228,7 +234,7 @@ template <class _Tp,
                             __libcpp_is_trivially_equality_comparable<_Tp, _Up>::value,
                         int> = 0>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
-__equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&, _Proj2&) {
+__equal_impl(_Tp* __first1, _Tp* __last1, _Up* __first2, _Up*, _Pred&, _Proj1&&, _Proj2&&) {
   return std::__constexpr_memcmp_equal(__first1, __first2, __element_count(__last1 - __first1));
 }
 
diff --git a/libcxx/include/__algorithm/find.h b/libcxx/include/__algorithm/find.h
index a7d9374b3a1c8..fa8f5b5ef8c5a 100644
--- a/libcxx/include/__algorithm/find.h
+++ b/libcxx/include/__algorithm/find.h
@@ -44,7 +44,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 // generic implementation
 template <class _Iter, class _Sent, class _Tp, class _Proj>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
-__find(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
+__find(_Iter __first, _Sent __last, const _Tp& __value, _Proj&& __proj) {
   for (; __first != __last; ++__first)
     if (std::__invoke(__proj, *__first) == __value)
       break;
@@ -88,7 +88,7 @@ template <class _Tp,
                             is_signed<_Tp>::value == is_signed<_Up>::value,
                         int> = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp*
-__find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj& __proj) {
+__find(_Tp* __first, _Tp* __last, const _Up& __value, _Proj&& __proj) {
   if (__value < numeric_limits<_Tp>::min() || __value > numeric_limits<_Tp>::max())
     return __last;
   return std::__find(__first, __last, _Tp(__value), __proj);
@@ -151,7 +151,7 @@ template <class _SegmentedIterator,
           class _Proj,
           __enable_if_t<__is_segmented_iterator<_SegmentedIterator>::value, int> = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
-__find(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj& __proj) {
+__find(_SegmentedIterator __first, _SegmentedIterator __last, const _Tp& __value, _Proj&& __proj) {
   return std::__find_segment_if(std::move(__first), std::move(__last), __find_segment<_Tp>(__value), __proj);
 }
 
diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h
index 86b4a3e2e3689..06d442bd029e9 100644
--- a/libcxx/include/__algorithm/find_end.h
+++ b/libcxx/include/__algorithm/find_end.h
@@ -37,9 +37,9 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1>
     _Sent1 __last1,
     _Iter2 __first2,
     _Sent2 __last2,
-    _Pred& __pred,
-    _Proj1& __proj1,
-    _Proj2& __proj2,
+    _Pred&& __pred,
+    _Proj1&& __proj1,
+    _Proj2&& __proj2,
     forward_iterator_tag,
     forward_iterator_tag) {
   // modeled after search algorithm
diff --git a/libcxx/include/__algorithm/find_segment_if.h b/libcxx/include/__algorithm/find_segment_if.h
index 9d6064f3e283a..f77b1af4042ff 100644
--- a/libcxx/include/__algorithm/find_segment_if.h
+++ b/libcxx/include/__algorithm/find_segment_if.h
@@ -26,7 +26,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _SegmentedIterator, class _Pred, class _Proj>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _SegmentedIterator
-__find_segment_if(_SegmentedIterator __first, _SegmentedIterator __last, _Pred __pred, _Proj& __proj) {
+__find_segment_if(_SegmentedIterator __first, _SegmentedIterator __last, _Pred __pred, _Proj&& __proj) {
   using _Traits = __segmented_iterator_traits<_SegmentedIterator>;
 
   auto __sfirst = _Traits::__segment(__first);
diff --git a/libcxx/include/__algorithm/lexicographical_compare.h b/libcxx/include/__algorithm/lexicographical_compare.h
index ebe7e3b56a292..0467cdcfb4eaf 100644
--- a/libcxx/include/__algorithm/lexicographical_compare.h
+++ b/libcxx/include/__algorithm/lexicographical_compare.h
@@ -41,7 +41,13 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Proj1, class _Proj2, class _Comp>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool __lexicographical_compare(
-    _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
+    _Iter1 __first1,
+    _Sent1 __last1,
+    _Iter2 __first2,
+    _Sent2 __last2,
+    _Comp&& __comp,
+    _Proj1&& __proj1,
+    _Proj2&& __proj2) {
   while (__first2 != __last2) {
     if (__first1 == __last1 ||
         std::__invoke(__comp, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
@@ -70,7 +76,7 @@ template <class _Tp,
                             __is_identity<_Proj1>::value && __is_identity<_Proj2>::value,
                         int> = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
-__lexicographical_compare(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Comp&, _Proj1&, _Proj2&) {
+__lexicographical_compare(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Comp&, _Proj1&&, _Proj2&&) {
   if constexpr (__is_trivially_lexicographically_comparable_v<_Tp, _Tp>) {
     auto __res =
         std::__constexpr_memcmp(__first1, __first2, __element_count(std::min(__last1 - __first1, __last2 - __first2)));
diff --git a/libcxx/include/__algorithm/lower_bound.h b/libcxx/include/__algorithm/lower_bound.h
index 4fba6748e6d71..d07533d0fca8c 100644
--- a/libcxx/include/__algorithm/lower_bound.h
+++ b/libcxx/include/__algorithm/lower_bound.h
@@ -31,8 +31,8 @@ template <class _AlgPolicy, class _Iter, class _Type, class _Proj, class _Comp>
     _Iter __first,
     const _Type& __value,
     typename iterator_traits<_Iter>::difference_type __len,
-    _Comp& __comp,
-    _Proj& __proj) {
+    _Comp&& __comp,
+    _Proj&& __proj) {
   while (__len != 0) {
     auto __l2 = std::__half_positive(__len);
     _Iter __m = __first;
@@ -58,7 +58,7 @@ template <class _AlgPolicy, class _Iter, class _Type, class _Proj, class _Comp>
 // comparisons.
 template <class _AlgPolicy, class _ForwardIterator, class _Sent, class _Type, class _Proj, class _Comp>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
-__lower_bound_onesided(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
+__lower_bound_onesided(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp&& __comp, _Proj&& __proj) {
   // step = 0, ensuring we can always short-circuit when distance is 1 later on
   if (__first == __last || !std::__invoke(__comp, std::__invoke(__proj, *__first), __value))
     return __first;
@@ -84,7 +84,7 @@ __lower_bound_onesided(_ForwardIterator __first, _Sent __last, const _Type& __va
 
 template <class _AlgPolicy, class _ForwardIterator, class _Sent, class _Type, class _Proj, class _Comp>
 [[__nodiscard__]] inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _ForwardIterator
-__lower_bound(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp& __comp, _Proj& __proj) {
+__lower_bound(_ForwardIterator __first, _Sent __last, const _Type& __value, _Comp&& __comp, _Proj&& __proj) {
   const auto __dist = _IterOps<_AlgPolicy>::distance(__first, __last);
   return std::__lower_bound_bisecting<_AlgPolicy>(__first, __value, __dist, __comp, __proj);
 }
diff --git a/libcxx/include/__algorithm/make_projected.h b/libcxx/include/__algorithm/make_projected.h
index 4a25822938751..950daf05a4f75 100644
--- a/libcxx/include/__algorithm/make_projected.h
+++ b/libcxx/include/__algorithm/make_projected.h
@@ -30,7 +30,7 @@ struct _ProjectedPred {
   _Pred& __pred; // Can be a unary or a binary predicate.
   _Proj& __proj;
 
-  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg)
+  _LIBCPP_CONSTEXPR _LIBCPP_HIDE_FROM_ABI _ProjectedPred(_Pred&& __pred_arg, _Proj&& __proj_arg)
       : __pred(__pred_arg), __proj(__proj_arg) {}
 
   template <class _Tp>
@@ -55,7 +55,7 @@ template <
     class _Pred,
     class _Proj,
     __enable_if_t<!(!is_member_pointer<__decay_t<_Pred> >::value && __is_identity<__decay_t<_Proj> >::value), int> = 0>
-_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj> __make_projected(_Pred& __pred, _Proj& __proj) {
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _ProjectedPred<_Pred, _Proj> __make_projected(_Pred&& __pred, _Proj&& __proj) {
   return _ProjectedPred<_Pred, _Proj>(__pred, __proj);
 }
 
@@ -79,7 +79,8 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 namespace ranges {
 
 template <class _Comp, class _Proj1, class _Proj2>
-_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
+_LIBCPP_HIDE_FROM_ABI constexpr decltype(auto)
+__make_projected_comp(_Comp&& __comp, _Proj1&& __proj1, _Proj2&& __proj2) {
   if constexpr (__is_identity<decay_t<_Proj1>>::value && __is_identity<decay_t<_Proj2>>::value &&
                 !is_member_pointer_v<decay_t<_Comp>>) {
     // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
diff --git a/libcxx/include/__algorithm/min_element.h b/libcxx/include/__algorithm/min_element.h
index db996365bf1de..9e5f4e43a03fd 100644
--- a/libcxx/include/__algorithm/min_element.h
+++ b/libcxx/include/__algorithm/min_element.h
@@ -29,7 +29,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Comp, class _Iter, class _Sent, class _Proj>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Iter
-__min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj& __proj) {
+__min_element(_Iter __first, _Sent __last, _Comp __comp, _Proj&& __proj) {
   if (__first == __last)
     return __first;
 
diff --git a/libcxx/include/__algorithm/minmax_element.h b/libcxx/include/__algorithm/minmax_element.h
index dc0c3a818cd57..51a0013f4b10f 100644
--- a/libcxx/include/__algorithm/minmax_element.h
+++ b/libcxx/include/__algorithm/minmax_element.h
@@ -25,11 +25,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Comp, class _Proj>
 class _MinmaxElementLessFunc {
-  _Comp& __comp_;
-  _Proj& __proj_;
+  _Comp&& __comp_;
+  _Proj&& __proj_;
 
 public:
-  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _MinmaxElementLessFunc(_Comp& __comp, _Proj& __proj)
+  _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _MinmaxElementLessFunc(_Comp&& __comp, _Proj&& __proj)
       : __comp_(__comp), __proj_(__proj) {}
 
   template <class _Iter>
@@ -40,7 +40,7 @@ class _MinmaxElementLessFunc {
 
 template <class _Iter, class _Sent, class _Proj, class _Comp>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter>
-__minmax_element_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+__minmax_element_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
   auto __less = _MinmaxElementLessFunc<_Comp, _Proj>(__comp, __proj);
 
   pair<_Iter, _Iter> __result(__first, __first);
diff --git a/libcxx/include/__algorithm/mismatch.h b/libcxx/include/__algorithm/mismatch.h
index a6836792c0581..cb2aa2e055752 100644
--- a/libcxx/include/__algorithm/mismatch.h
+++ b/libcxx/include/__algorithm/mismatch.h
@@ -39,7 +39,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _Iter1, class _Sent1, class _Iter2, class _Pred, class _Proj1, class _Proj2>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2>
-__mismatch_loop(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+__mismatch_loop(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) {
   while (__first1 != __last1) {
     if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
       break;
@@ -51,7 +51,7 @@ __mismatch_loop(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred,
 
 template <class _Iter1, class _Sent1, class _Iter2, class _Pred, class _Proj1, class _Proj2>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2>
-__mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+__mismatch(_Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) {
   return std::__mismatch_loop(__first1, __last1, __first2, __pred, __proj1, __proj2);
 }
 
@@ -126,7 +126,7 @@ template <class _Tp,
                             __is_identity<_Proj1>::value && __is_identity<_Proj2>::value,
                         int> = 0>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
-__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred&, _Proj1&, _Proj2&) {
+__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred&, _Proj1&&, _Proj2&&) {
   return std::__mismatch_vectorized(__first1, __last1, __first2);
 }
 
@@ -139,7 +139,7 @@ template <class _Tp,
                             __can_map_to_integer_v<_Tp> && __libcpp_is_trivially_equality_comparable<_Tp, _Tp>::value,
                         int> = 0>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
-__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) {
   if (__libcpp_is_constant_evaluated()) {
     return std::__mismatch_loop(__first1, __last1, __first2, __pred, __proj1, __proj2);
   } else {
@@ -168,7 +168,13 @@ mismatch(_InputIterator1 __first1, _InputIterator1 __last1, _InputIterator2 __fi
 #if _LIBCPP_STD_VER >= 14
 template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, class _Proj1, class _Proj2>
 [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Iter1, _Iter2> __mismatch(
-    _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+    _Iter1 __first1,
+    _Sent1 __last1,
+    _Iter2 __first2,
+    _Sent2 __last2,
+    _Pred&& __pred,
+    _Proj1&& __proj1,
+    _Proj2&& __proj2) {
   while (__first1 != __last1 && __first2 != __last2) {
     if (!std::__invoke(__pred, std::__invoke(__proj1, *__first1), std::__invoke(__proj2, *__first2)))
       break;
@@ -179,8 +185,8 @@ template <class _Iter1, class _Sent1, class _Iter2, class _Sent2, class _Pred, c
 }
 
 template <class _Tp, class _Pred, class _Proj1, class _Proj2>
-[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*>
-__mismatch(_Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+[[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_Tp*, _Tp*> __mismatch(
+    _Tp* __first1, _Tp* __last1, _Tp* __first2, _Tp* __last2, _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) {
   auto __len = std::min(__last1 - __first1, __last2 - __first2);
   return std::__mismatch(__first1, __first1 + __len, __first2, __pred, __proj1, __proj2);
 }
diff --git a/libcxx/include/__algorithm/ranges_ends_with.h b/libcxx/include/__algorithm/ranges_ends_with.h
index 3621bda389123..24d9ce6293f29 100644
--- a/libcxx/include/__algorithm/ranges_ends_with.h
+++ b/libcxx/include/__algorithm/ranges_ends_with.h
@@ -44,9 +44,9 @@ struct __ends_with {
       _Sent1 __last1,
       _Iter2 __first2,
       _Sent2 __last2,
-      _Pred& __pred,
-      _Proj1& __proj1,
-      _Proj2& __proj2) {
+      _Pred&& __pred,
+      _Proj1&& __proj1,
+      _Proj2&& __proj2) {
     auto __rbegin1 = std::make_reverse_iterator(__last1);
     auto __rend1   = std::make_reverse_iterator(__first1);
     auto __rbegin2 = std::make_reverse_iterator(__last2);
@@ -61,9 +61,9 @@ struct __ends_with {
       _Sent1 __last1,
       _Iter2 __first2,
       _Sent2 __last2,
-      _Pred& __pred,
-      _Proj1& __proj1,
-      _Proj2& __proj2) {
+      _Pred&& __pred,
+      _Proj1&& __proj1,
+      _Proj2&& __proj2) {
     if constexpr (std::bidirectional_iterator<_Sent1> && std::bidirectional_iterator<_Sent2> &&
                   (!std::random_access_iterator<_Sent1>) && (!std::random_access_iterator<_Sent2>)) {
       return __ends_with_fn_impl_bidirectional(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
@@ -101,9 +101,9 @@ struct __ends_with {
       _Sent1 __last1,
       _Iter2 __first2,
       _Sent2 __last2,
-      _Pred& __pred,
-      _Proj1& __proj1,
-      _Proj2& __proj2,
+      _Pred&& __pred,
+      _Proj1&& __proj1,
+      _Proj2&& __proj2,
       _Offset __offset) {
     if constexpr (std::bidirectional_iterator<_Sent1> && std::bidirectional_iterator<_Sent2> &&
                   !std::random_access_iterator<_Sent1> && !std::random_access_iterator<_Sent2>) {
diff --git a/libcxx/include/__algorithm/ranges_find.h b/libcxx/include/__algorithm/ranges_find.h
index 1eac4cfa02a4a..0a3d1e0884a39 100644
--- a/libcxx/include/__algorithm/ranges_find.h
+++ b/libcxx/include/__algorithm/ranges_find.h
@@ -39,7 +39,7 @@ namespace ranges {
 struct __find {
   template <class _Iter, class _Sent, class _Tp, class _Proj>
   _LIBCPP_HIDE_FROM_ABI static constexpr _Iter
-  __find_unwrap(_Iter __first, _Sent __last, const _Tp& __value, _Proj& __proj) {
+  __find_unwrap(_Iter __first, _Sent __last, const _Tp& __value, _Proj&& __proj) {
     if constexpr (forward_iterator<_Iter>) {
       auto [__first_un, __last_un] = std::__unwrap_range(__first, std::move(__last));
       return std::__rewrap_range<_Sent>(
diff --git a/libcxx/include/__algorithm/ranges_find_first_of.h b/libcxx/include/__algorithm/ranges_find_first_of.h
index 102e16dd7a55b..cbdd3157a1569 100644
--- a/libcxx/include/__algorithm/ranges_find_first_of.h
+++ b/libcxx/include/__algorithm/ranges_find_first_of.h
@@ -39,9 +39,9 @@ struct __find_first_of {
       _Sent1 __last1,
       _Iter2 __first2,
       _Sent2 __last2,
-      _Pred& __pred,
-      _Proj1& __proj1,
-      _Proj2& __proj2) {
+      _Pred&& __pred,
+      _Proj1&& __proj1,
+      _Proj2&& __proj2) {
     for (; __first1 != __last1; ++__first1) {
       for (auto __j = __first2; __j != __last2; ++__j) {
         if (std::invoke(__pred, std::invoke(__proj1, *__first1), std::invoke(__proj2, *__j)))
diff --git a/libcxx/include/__algorithm/ranges_find_if.h b/libcxx/include/__algorithm/ranges_find_if.h
index ed6406e6186a3..76ffdf7764f8d 100644
--- a/libcxx/include/__algorithm/ranges_find_if.h
+++ b/libcxx/include/__algorithm/ranges_find_if.h
@@ -34,7 +34,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 namespace ranges {
 
 template <class _Ip, class _Sp, class _Pred, class _Proj>
-_LIBCPP_HIDE_FROM_ABI constexpr _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred& __pred, _Proj& __proj) {
+_LIBCPP_HIDE_FROM_ABI constexpr _Ip __find_if_impl(_Ip __first, _Sp __last, _Pred&& __pred, _Proj&& __proj) {
   for (; __first != __last; ++__first) {
     if (std::invoke(__pred, std::invoke(__proj, *__first)))
       break;
diff --git a/libcxx/include/__algorithm/ranges_find_last.h b/libcxx/include/__algorithm/ranges_find_last.h
index e7dae1704c2ea..2f1241297d1ed 100644
--- a/libcxx/include/__algorithm/ranges_find_last.h
+++ b/libcxx/include/__algorithm/ranges_find_last.h
@@ -39,7 +39,7 @@ namespace ranges {
 
 template <class _Iter, class _Sent, class _Pred, class _Proj>
 _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
-__find_last_impl(_Iter __first, _Sent __last, _Pred __pred, _Proj& __proj) {
+__find_last_impl(_Iter __first, _Sent __last, _Pred __pred, _Proj&& __proj) {
   if (__first == __last) {
     return subrange<_Iter>(__first, __first);
   }
diff --git a/libcxx/include/__algorithm/ranges_for_each.h b/libcxx/include/__algorithm/ranges_for_each.h
index de39bc5522753..feae83ca14494 100644
--- a/libcxx/include/__algorithm/ranges_for_each.h
+++ b/libcxx/include/__algorithm/ranges_for_each.h
@@ -40,7 +40,7 @@ struct __for_each {
 private:
   template <class _Iter, class _Sent, class _Proj, class _Func>
   _LIBCPP_HIDE_FROM_ABI constexpr static for_each_result<_Iter, _Func>
-  __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj& __proj) {
+  __for_each_impl(_Iter __first, _Sent __last, _Func& __func, _Proj&& __proj) {
     for (; __first != __last; ++__first)
       std::invoke(__func, std::invoke(__proj, *__first));
     return {std::move(__first), std::move(__func)};
diff --git a/libcxx/include/__algorithm/ranges_is_heap.h b/libcxx/include/__algorithm/ranges_is_heap.h
index b4724abfb62a5..c2139fad170ed 100644
--- a/libcxx/include/__algorithm/ranges_is_heap.h
+++ b/libcxx/include/__algorithm/ranges_is_heap.h
@@ -37,7 +37,7 @@ namespace ranges {
 struct __is_heap {
   template <class _Iter, class _Sent, class _Proj, class _Comp>
   _LIBCPP_HIDE_FROM_ABI constexpr static bool
-  __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto __last_iter        = ranges::next(__first, __last);
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
 
diff --git a/libcxx/include/__algorithm/ranges_is_heap_until.h b/libcxx/include/__algorithm/ranges_is_heap_until.h
index 25f3b484faa66..d73cf5f8a1498 100644
--- a/libcxx/include/__algorithm/ranges_is_heap_until.h
+++ b/libcxx/include/__algorithm/ranges_is_heap_until.h
@@ -38,7 +38,7 @@ namespace ranges {
 struct __is_heap_until {
   template <class _Iter, class _Sent, class _Proj, class _Comp>
   _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
-  __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto __last_iter        = ranges::next(__first, __last);
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
 
diff --git a/libcxx/include/__algorithm/ranges_is_partitioned.h b/libcxx/include/__algorithm/ranges_is_partitioned.h
index 8092abfcd1de3..de964ad916c12 100644
--- a/libcxx/include/__algorithm/ranges_is_partitioned.h
+++ b/libcxx/include/__algorithm/ranges_is_partitioned.h
@@ -34,7 +34,7 @@ namespace ranges {
 struct __is_partitioned {
   template <class _Iter, class _Sent, class _Proj, class _Pred>
   _LIBCPP_HIDE_FROM_ABI constexpr static bool
-  __is_partitioned_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+  __is_partitioned_impl(_Iter __first, _Sent __last, _Pred&& __pred, _Proj&& __proj) {
     for (; __first != __last; ++__first) {
       if (!std::invoke(__pred, std::invoke(__proj, *__first)))
         break;
diff --git a/libcxx/include/__algorithm/ranges_is_permutation.h b/libcxx/include/__algorithm/ranges_is_permutation.h
index 53a431d2ba425..e2e31dd23c233 100644
--- a/libcxx/include/__algorithm/ranges_is_permutation.h
+++ b/libcxx/include/__algorithm/ranges_is_permutation.h
@@ -40,9 +40,9 @@ struct __is_permutation {
       _Sent1 __last1,
       _Iter2 __first2,
       _Sent2 __last2,
-      _Pred& __pred,
-      _Proj1& __proj1,
-      _Proj2& __proj2) {
+      _Pred&& __pred,
+      _Proj1&& __proj1,
+      _Proj2&& __proj2) {
     return std::__is_permutation<_RangeAlgPolicy>(
         std::move(__first1), std::move(__last1), std::move(__first2), std::move(__last2), __pred, __proj1, __proj2);
   }
diff --git a/libcxx/include/__algorithm/ranges_is_sorted_until.h b/libcxx/include/__algorithm/ranges_is_sorted_until.h
index f2e51c264e4a7..716ba1825499e 100644
--- a/libcxx/include/__algorithm/ranges_is_sorted_until.h
+++ b/libcxx/include/__algorithm/ranges_is_sorted_until.h
@@ -35,7 +35,7 @@ namespace ranges {
 
 template <class _Iter, class _Sent, class _Proj, class _Comp>
 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
-__is_sorted_until_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+__is_sorted_until_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
   if (__first == __last)
     return __first;
   auto __i = __first;
diff --git a/libcxx/include/__algorithm/ranges_lexicographical_compare.h b/libcxx/include/__algorithm/ranges_lexicographical_compare.h
index ec12b0cc29ace..260fe377a9110 100644
--- a/libcxx/include/__algorithm/ranges_lexicographical_compare.h
+++ b/libcxx/include/__algorithm/ranges_lexicographical_compare.h
@@ -40,9 +40,9 @@ struct __lexicographical_compare {
       _Sent1 __last1,
       _Iter2 __first2,
       _Sent2 __last2,
-      _Comp& __comp,
-      _Proj1& __proj1,
-      _Proj2& __proj2) {
+      _Comp&& __comp,
+      _Proj1&& __proj1,
+      _Proj2&& __proj2) {
     auto [__first1_un, __last1_un] = std::__unwrap_range(std::move(__first1), std::move(__last1));
     auto [__first2_un, __last2_un] = std::__unwrap_range(std::move(__first2), std::move(__last2));
     return std::__lexicographical_compare(
diff --git a/libcxx/include/__algorithm/ranges_make_heap.h b/libcxx/include/__algorithm/ranges_make_heap.h
index 97148f77b4181..43928682dbe39 100644
--- a/libcxx/include/__algorithm/ranges_make_heap.h
+++ b/libcxx/include/__algorithm/ranges_make_heap.h
@@ -43,7 +43,7 @@ namespace ranges {
 struct __make_heap {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
   _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
-  __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
diff --git a/libcxx/include/__algorithm/ranges_min_element.h b/libcxx/include/__algorithm/ranges_min_element.h
index fb92ae56bcd62..ef7ce679e8aa1 100644
--- a/libcxx/include/__algorithm/ranges_min_element.h
+++ b/libcxx/include/__algorithm/ranges_min_element.h
@@ -35,7 +35,7 @@ namespace ranges {
 
 // TODO(ranges): `ranges::min_element` can now simply delegate to `std::__min_element`.
 template <class _Ip, class _Sp, class _Proj, class _Comp>
-_LIBCPP_HIDE_FROM_ABI constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp& __comp, _Proj& __proj) {
+_LIBCPP_HIDE_FROM_ABI constexpr _Ip __min_element_impl(_Ip __first, _Sp __last, _Comp&& __comp, _Proj&& __proj) {
   if (__first == __last)
     return __first;
 
diff --git a/libcxx/include/__algorithm/ranges_mismatch.h b/libcxx/include/__algorithm/ranges_mismatch.h
index b35747dfa43a2..7c6a00b0efec4 100644
--- a/libcxx/include/__algorithm/ranges_mismatch.h
+++ b/libcxx/include/__algorithm/ranges_mismatch.h
@@ -42,7 +42,7 @@ using mismatch_result = in_in_result<_I1, _I2>;
 struct __mismatch {
   template <class _I1, class _S1, class _I2, class _S2, class _Pred, class _Proj1, class _Proj2>
   static _LIBCPP_HIDE_FROM_ABI constexpr mismatch_result<_I1, _I2>
-  __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+  __go(_I1 __first1, _S1 __last1, _I2 __first2, _S2 __last2, _Pred&& __pred, _Proj1&& __proj1, _Proj2&& __proj2) {
     if constexpr (forward_iterator<_I1> && forward_iterator<_I2>) {
       auto __range1 = std::__unwrap_range(__first1, __last1);
       auto __range2 = std::__unwrap_range(__first2, __last2);
diff --git a/libcxx/include/__algorithm/ranges_none_of.h b/libcxx/include/__algorithm/ranges_none_of.h
index a1612826220d9..7430a69f473b7 100644
--- a/libcxx/include/__algorithm/ranges_none_of.h
+++ b/libcxx/include/__algorithm/ranges_none_of.h
@@ -33,7 +33,7 @@ namespace ranges {
 struct __none_of {
   template <class _Iter, class _Sent, class _Proj, class _Pred>
   _LIBCPP_HIDE_FROM_ABI constexpr static bool
-  __none_of_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+  __none_of_impl(_Iter __first, _Sent __last, _Pred&& __pred, _Proj&& __proj) {
     for (; __first != __last; ++__first) {
       if (std::invoke(__pred, std::invoke(__proj, *__first)))
         return false;
diff --git a/libcxx/include/__algorithm/ranges_nth_element.h b/libcxx/include/__algorithm/ranges_nth_element.h
index e92c51e713cb4..66f74e8ea92c8 100644
--- a/libcxx/include/__algorithm/ranges_nth_element.h
+++ b/libcxx/include/__algorithm/ranges_nth_element.h
@@ -42,7 +42,7 @@ namespace ranges {
 struct __nth_element {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
   _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
-  __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
diff --git a/libcxx/include/__algorithm/ranges_partial_sort.h b/libcxx/include/__algorithm/ranges_partial_sort.h
index fc8a1f7d93065..2231942e70f4e 100644
--- a/libcxx/include/__algorithm/ranges_partial_sort.h
+++ b/libcxx/include/__algorithm/ranges_partial_sort.h
@@ -44,7 +44,7 @@ namespace ranges {
 struct __partial_sort {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
   _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
-  __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __partial_sort_fn_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
     return std::__partial_sort<_RangeAlgPolicy>(std::move(__first), std::move(__middle), __last, __projected_comp);
   }
diff --git a/libcxx/include/__algorithm/ranges_partition_copy.h b/libcxx/include/__algorithm/ranges_partition_copy.h
index 47878a4017233..2e3059a520c9b 100644
--- a/libcxx/include/__algorithm/ranges_partition_copy.h
+++ b/libcxx/include/__algorithm/ranges_partition_copy.h
@@ -49,8 +49,8 @@ struct __partition_copy {
       _Sent&& __last,
       _OutIter1&& __out_true,
       _OutIter2&& __out_false,
-      _Pred& __pred,
-      _Proj& __proj) {
+      _Pred&& __pred,
+      _Proj&& __proj) {
     for (; __first != __last; ++__first) {
       if (std::invoke(__pred, std::invoke(__proj, *__first))) {
         *__out_true = *__first;
diff --git a/libcxx/include/__algorithm/ranges_partition_point.h b/libcxx/include/__algorithm/ranges_partition_point.h
index 324efbb86d64c..cd9f18250790a 100644
--- a/libcxx/include/__algorithm/ranges_partition_point.h
+++ b/libcxx/include/__algorithm/ranges_partition_point.h
@@ -39,7 +39,7 @@ struct __partition_point {
   // TODO(ranges): delegate to the classic algorithm.
   template <class _Iter, class _Sent, class _Proj, class _Pred>
   _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
-  __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred& __pred, _Proj& __proj) {
+  __partition_point_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
     auto __len = ranges::distance(__first, __last);
 
     while (__len != 0) {
diff --git a/libcxx/include/__algorithm/ranges_pop_heap.h b/libcxx/include/__algorithm/ranges_pop_heap.h
index eccf54c094e3d..87e4387fd66a9 100644
--- a/libcxx/include/__algorithm/ranges_pop_heap.h
+++ b/libcxx/include/__algorithm/ranges_pop_heap.h
@@ -43,7 +43,7 @@ namespace ranges {
 struct __pop_heap {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
   _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
-  __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __pop_heap_fn_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto __last_iter = ranges::next(__first, __last);
     auto __len       = __last_iter - __first;
 
diff --git a/libcxx/include/__algorithm/ranges_push_heap.h b/libcxx/include/__algorithm/ranges_push_heap.h
index c5e0465bdcfe1..3823b3819b1d0 100644
--- a/libcxx/include/__algorithm/ranges_push_heap.h
+++ b/libcxx/include/__algorithm/ranges_push_heap.h
@@ -43,7 +43,7 @@ namespace ranges {
 struct __push_heap {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
   _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
-  __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
diff --git a/libcxx/include/__algorithm/ranges_remove_copy_if.h b/libcxx/include/__algorithm/ranges_remove_copy_if.h
index 87136ae8258d6..e08972c4d4efe 100644
--- a/libcxx/include/__algorithm/ranges_remove_copy_if.h
+++ b/libcxx/include/__algorithm/ranges_remove_copy_if.h
@@ -43,7 +43,7 @@ using remove_copy_if_result = in_out_result<_InIter, _OutIter>;
 
 template <class _InIter, class _Sent, class _OutIter, class _Proj, class _Pred>
 _LIBCPP_HIDE_FROM_ABI constexpr in_out_result<_InIter, _OutIter>
-__remove_copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, _Proj& __proj) {
+__remove_copy_if_impl(_InIter __first, _Sent __last, _OutIter __result, _Pred&& __pred, _Proj&& __proj) {
   for (; __first != __last; ++__first) {
     if (!std::invoke(__pred, std::invoke(__proj, *__first))) {
       *__result = *__first;
diff --git a/libcxx/include/__algorithm/ranges_remove_if.h b/libcxx/include/__algorithm/ranges_remove_if.h
index 384b3d41d0801..fe9de10a35464 100644
--- a/libcxx/include/__algorithm/ranges_remove_if.h
+++ b/libcxx/include/__algorithm/ranges_remove_if.h
@@ -38,7 +38,7 @@ namespace ranges {
 
 template <class _Iter, class _Sent, class _Proj, class _Pred>
 _LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
-__remove_if_impl(_Iter __first, _Sent __last, _Pred& __pred, _Proj& __proj) {
+__remove_if_impl(_Iter __first, _Sent __last, _Pred&& __pred, _Proj&& __proj) {
   auto __new_end = ranges::__find_if_impl(__first, __last, __pred, __proj);
   if (__new_end == __last)
     return {__new_end, __new_end};
diff --git a/libcxx/include/__algorithm/ranges_replace_copy_if.h b/libcxx/include/__algorithm/ranges_replace_copy_if.h
index 852ec45edaefe..00cee8689d067 100644
--- a/libcxx/include/__algorithm/ranges_replace_copy_if.h
+++ b/libcxx/include/__algorithm/ranges_replace_copy_if.h
@@ -38,7 +38,7 @@ using replace_copy_if_result = in_out_result<_InIter, _OutIter>;
 
 template <class _InIter, class _Sent, class _OutIter, class _Pred, class _Type, class _Proj>
 _LIBCPP_HIDE_FROM_ABI constexpr replace_copy_if_result<_InIter, _OutIter> __replace_copy_if_impl(
-    _InIter __first, _Sent __last, _OutIter __result, _Pred& __pred, const _Type& __new_value, _Proj& __proj) {
+    _InIter __first, _Sent __last, _OutIter __result, _Pred&& __pred, const _Type& __new_value, _Proj&& __proj) {
   while (__first != __last) {
     if (std::invoke(__pred, std::invoke(__proj, *__first)))
       *__result = __new_value;
diff --git a/libcxx/include/__algorithm/ranges_replace_if.h b/libcxx/include/__algorithm/ranges_replace_if.h
index baa566810b5d0..1ca1470cdd4e9 100644
--- a/libcxx/include/__algorithm/ranges_replace_if.h
+++ b/libcxx/include/__algorithm/ranges_replace_if.h
@@ -34,7 +34,7 @@ namespace ranges {
 
 template <class _Iter, class _Sent, class _Type, class _Proj, class _Pred>
 _LIBCPP_HIDE_FROM_ABI constexpr _Iter
-__replace_if_impl(_Iter __first, _Sent __last, _Pred& __pred, const _Type& __new_value, _Proj& __proj) {
+__replace_if_impl(_Iter __first, _Sent __last, _Pred&& __pred, const _Type& __new_value, _Proj&& __proj) {
   for (; __first != __last; ++__first) {
     if (std::invoke(__pred, std::invoke(__proj, *__first)))
       *__first = __new_value;
diff --git a/libcxx/include/__algorithm/ranges_search.h b/libcxx/include/__algorithm/ranges_search.h
index b711512039635..5d2306733d079 100644
--- a/libcxx/include/__algorithm/ranges_search.h
+++ b/libcxx/include/__algorithm/ranges_search.h
@@ -40,9 +40,9 @@ struct __search {
       _Sent1 __last1,
       _Iter2 __first2,
       _Sent2 __last2,
-      _Pred& __pred,
-      _Proj1& __proj1,
-      _Proj2& __proj2) {
+      _Pred&& __pred,
+      _Proj1&& __proj1,
+      _Proj2&& __proj2) {
     if constexpr (sized_sentinel_for<_Sent2, _Iter2>) {
       auto __size2 = ranges::distance(__first2, __last2);
       if (__size2 == 0)
diff --git a/libcxx/include/__algorithm/ranges_search_n.h b/libcxx/include/__algorithm/ranges_search_n.h
index 81b568c0965fd..90d9bd7af9469 100644
--- a/libcxx/include/__algorithm/ranges_search_n.h
+++ b/libcxx/include/__algorithm/ranges_search_n.h
@@ -42,7 +42,7 @@ namespace ranges {
 struct __search_n {
   template <class _Iter1, class _Sent1, class _SizeT, class _Type, class _Pred, class _Proj>
   _LIBCPP_HIDE_FROM_ABI static constexpr subrange<_Iter1> __ranges_search_n_impl(
-      _Iter1 __first, _Sent1 __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
+      _Iter1 __first, _Sent1 __last, _SizeT __count, const _Type& __value, _Pred&& __pred, _Proj&& __proj) {
     if (__count == 0)
       return {__first, __first};
 
diff --git a/libcxx/include/__algorithm/ranges_sort.h b/libcxx/include/__algorithm/ranges_sort.h
index 2afad4c41301e..83008484961fb 100644
--- a/libcxx/include/__algorithm/ranges_sort.h
+++ b/libcxx/include/__algorithm/ranges_sort.h
@@ -42,7 +42,7 @@ namespace ranges {
 struct __sort {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
   _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
-  __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __sort_fn_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
diff --git a/libcxx/include/__algorithm/ranges_sort_heap.h b/libcxx/include/__algorithm/ranges_sort_heap.h
index d3e20874fac50..33c95520d13ae 100644
--- a/libcxx/include/__algorithm/ranges_sort_heap.h
+++ b/libcxx/include/__algorithm/ranges_sort_heap.h
@@ -43,7 +43,7 @@ namespace ranges {
 struct __sort_heap {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
   _LIBCPP_HIDE_FROM_ABI constexpr static _Iter
-  __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
diff --git a/libcxx/include/__algorithm/ranges_stable_sort.h b/libcxx/include/__algorithm/ranges_stable_sort.h
index 6e17d0d0c7ec4..330a96582da67 100644
--- a/libcxx/include/__algorithm/ranges_stable_sort.h
+++ b/libcxx/include/__algorithm/ranges_stable_sort.h
@@ -42,7 +42,7 @@ namespace ranges {
 struct __stable_sort {
   template <class _Iter, class _Sent, class _Comp, class _Proj>
   _LIBCPP_HIDE_FROM_ABI static _LIBCPP_CONSTEXPR_SINCE_CXX26 _Iter
-  __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
+  __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
     auto __last_iter = ranges::next(__first, __last);
 
     auto&& __projected_comp = std::__make_projected(__comp, __proj);
diff --git a/libcxx/include/__algorithm/ranges_transform.h b/libcxx/include/__algorithm/ranges_transform.h
index 091311821968c..ca6737e42afce 100644
--- a/libcxx/include/__algorithm/ranges_transform.h
+++ b/libcxx/include/__algorithm/ranges_transform.h
@@ -45,7 +45,7 @@ struct __transform {
 private:
   template <class _InIter, class _Sent, class _OutIter, class _Func, class _Proj>
   _LIBCPP_HIDE_FROM_ABI static constexpr unary_transform_result<_InIter, _OutIter>
-  __unary(_InIter __first, _Sent __last, _OutIter __result, _Func& __operation, _Proj& __projection) {
+  __unary(_InIter __first, _Sent __last, _OutIter __result, _Func& __operation, _Proj&& __projection) {
     while (__first != __last) {
       *__result = std::invoke(__operation, std::invoke(__projection, *__first));
       ++__first;
@@ -70,8 +70,8 @@ struct __transform {
            _Sent2 __last2,
            _OutIter __result,
            _Func& __binary_operation,
-           _Proj1& __projection1,
-           _Proj2& __projection2) {
+           _Proj1&& __projection1,
+           _Proj2&& __projection2) {
     while (__first1 != __last1 && __first2 != __last2) {
       *__result =
           std::invoke(__binary_operation, std::invoke(__projection1, *__first1), std::invoke(__projection2, *__first2));
diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h
index 161fd39d861a6..da340462d49f4 100644
--- a/libcxx/include/__algorithm/search.h
+++ b/libcxx/include/__algorithm/search.h
@@ -37,7 +37,13 @@ template <class _AlgPolicy,
           class _Proj1,
           class _Proj2>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_forward_impl(
-    _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+    _Iter1 __first1,
+    _Sent1 __last1,
+    _Iter2 __first2,
+    _Sent2 __last2,
+    _Pred&& __pred,
+    _Proj1&& __proj1,
+    _Proj2&& __proj2) {
   if (__first2 == __last2)
     return std::make_pair(__first1, __first1); // Everything matches an empty sequence
   while (true) {
@@ -85,9 +91,9 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __searc
     _Sent1 __last1,
     _Iter2 __first2,
     _Sent2 __last2,
-    _Pred& __pred,
-    _Proj1& __proj1,
-    _Proj2& __proj2,
+    _Pred&& __pred,
+    _Proj1&& __proj1,
+    _Proj2&& __proj2,
     _DiffT1 __size1,
     _DiffT2 __size2) {
   const _Iter1 __s = __first1 + __size1 - _DiffT1(__size2 - 1); // Start of pattern match can't go beyond here
@@ -128,7 +134,13 @@ template <class _Iter1,
                             __has_random_access_iterator_category<_Iter2>::value,
                         int> = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl(
-    _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+    _Iter1 __first1,
+    _Sent1 __last1,
+    _Iter2 __first2,
+    _Sent2 __last2,
+    _Pred&& __pred,
+    _Proj1&& __proj1,
+    _Proj2&& __proj2) {
   auto __size2 = __last2 - __first2;
   if (__size2 == 0)
     return std::make_pair(__first1, __first1);
@@ -155,7 +167,13 @@ template <
                         __has_random_access_iterator_category<_Iter2>::value),
                   int> = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1> __search_impl(
-    _Iter1 __first1, _Sent1 __last1, _Iter2 __first2, _Sent2 __last2, _Pred& __pred, _Proj1& __proj1, _Proj2& __proj2) {
+    _Iter1 __first1,
+    _Sent1 __last1,
+    _Iter2 __first2,
+    _Sent2 __last2,
+    _Pred&& __pred,
+    _Proj1&& __proj1,
+    _Proj2&& __proj2) {
   return std::__search_forward_impl<_ClassicAlgPolicy>(__first1, __last1, __first2, __last2, __pred, __proj1, __proj2);
 }
 
diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h
index 38474e1b2379d..9a8d0c3577f13 100644
--- a/libcxx/include/__algorithm/search_n.h
+++ b/libcxx/include/__algorithm/search_n.h
@@ -33,7 +33,7 @@ _LIBCPP_BEGIN_NAMESPACE_STD
 
 template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_n_forward_impl(
-    _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
+    _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred&& __pred, _Proj&& __proj) {
   if (__count <= 0)
     return std::make_pair(__first, __first);
   while (true) {
@@ -70,7 +70,7 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter> __search_
 
 template <class _AlgPolicy, class _Pred, class _Iter, class _Sent, class _SizeT, class _Type, class _Proj, class _DiffT>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 std::pair<_Iter, _Iter> __search_n_random_access_impl(
-    _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred& __pred, _Proj& __proj, _DiffT __size1) {
+    _Iter __first, _Sent __last, _SizeT __count, const _Type& __value, _Pred&& __pred, _Proj&& __proj, _DiffT __size1) {
   using difference_type = typename iterator_traits<_Iter>::difference_type;
   if (__count == 0)
     return std::make_pair(__first, __first);
@@ -117,7 +117,7 @@ template <class _Iter,
           class _Proj,
           __enable_if_t<__has_random_access_iterator_category<_Iter>::value, int> = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter, _Iter>
-__search_n_impl(_Iter __first, _Sent __last, _DiffT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
+__search_n_impl(_Iter __first, _Sent __last, _DiffT __count, const _Type& __value, _Pred&& __pred, _Proj&& __proj) {
   return std::__search_n_random_access_impl<_ClassicAlgPolicy>(
       __first, __last, __count, __value, __pred, __proj, __last - __first);
 }
@@ -132,7 +132,7 @@ template <class _Iter1,
                             !__has_random_access_iterator_category<_Iter1>::value,
                         int> = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 pair<_Iter1, _Iter1>
-__search_n_impl(_Iter1 __first, _Sent1 __last, _DiffT __count, const _Type& __value, _Pred& __pred, _Proj& __proj) {
+__search_n_impl(_Iter1 __first, _Sent1 __last, _DiffT __count, const _Type& __value, _Pred&& __pred, _Proj&& __proj) {
   return std::__search_n_forward_impl<_ClassicAlgPolicy>(__first, __last, __count, __value, __pred, __proj);
 }
 
diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h
index 4332b62544b40..62b7c9a73b83e 100644
--- a/libcxx/include/__algorithm/sort.h
+++ b/libcxx/include/__algorithm/sort.h
@@ -876,7 +876,7 @@ __sort<__less<long double>&, long double*>(long double*, long double*, __less<lo
 
 template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-__sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
+__sort_dispatch(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp) {
   typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
   difference_type __depth_limit = 2 * std::__log2i(__last - __first);
 
@@ -941,7 +941,7 @@ _LIBCPP_HIDE_FROM_ABI void __sort_dispatch(_Type* __first, _Type* __last, ranges
 
 template <class _AlgPolicy, class _RandomAccessIterator, class _Comp>
 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void
-__sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp& __comp) {
+__sort_impl(_RandomAccessIterator __first, _RandomAccessIterator __last, _Comp&& __comp) {
   std::__debug_randomize_range<_AlgPolicy>(__first, __last);
 
   if (__libcpp_is_constant_evaluated()) {