[libc++][ranges] Implement `std::ranges::partial_sort_copy`.
Differential Revision: https://reviews.llvm.org/D130532
NOKEYCHECK=True
GitOrigin-RevId: db7d7959787ed68f037e2a6e5a70bb0d8c17ab27
diff --git a/include/__algorithm/make_heap.h b/include/__algorithm/make_heap.h
index bf9dd96..0aa67d1 100644
--- a/include/__algorithm/make_heap.h
+++ b/include/__algorithm/make_heap.h
@@ -25,7 +25,7 @@
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
-void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
+void __make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
using _CompRef = typename __comp_ref_type<_Compare>::type;
_CompRef __comp_ref = __comp;
@@ -34,7 +34,7 @@
if (__n > 1) {
// start from the first parent, there is no need to consider children
for (difference_type __start = (__n - 2) / 2; __start >= 0; --__start) {
- std::__sift_down<_AlgPolicy, _CompRef>(__first, __comp_ref, __n, __first + __start);
+ std::__sift_down<_AlgPolicy>(__first, __comp_ref, __n, __first + __start);
}
}
}
diff --git a/include/__algorithm/make_projected.h b/include/__algorithm/make_projected.h
index 64fc3df..6c1d156 100644
--- a/include/__algorithm/make_projected.h
+++ b/include/__algorithm/make_projected.h
@@ -14,51 +14,91 @@
#include <__functional/identity.h>
#include <__functional/invoke.h>
#include <__type_traits/decay.h>
+#include <__type_traits/enable_if.h>
+#include <__type_traits/integral_constant.h>
#include <__type_traits/is_member_pointer.h>
+#include <__type_traits/is_same.h>
+#include <__utility/declval.h>
#include <__utility/forward.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class _Pred, class _Proj>
+struct _ProjectedPred {
+ _Pred& __pred; // Can be a unary or a binary predicate.
+ _Proj& __proj;
+
+ _LIBCPP_CONSTEXPR _ProjectedPred(_Pred& __pred_arg, _Proj& __proj_arg) : __pred(__pred_arg), __proj(__proj_arg) {}
+
+ template <class _Tp>
+ typename __invoke_of<_Pred&,
+ decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_Tp>()))
+ >::type
+ _LIBCPP_CONSTEXPR operator()(_Tp&& __v) const {
+ return std::__invoke(__pred, std::__invoke(__proj, std::forward<_Tp>(__v)));
+ }
+
+ template <class _T1, class _T2>
+ typename __invoke_of<_Pred&,
+ decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T1>())),
+ decltype(std::__invoke(std::declval<_Proj&>(), std::declval<_T2>()))
+ >::type
+ _LIBCPP_CONSTEXPR operator()(_T1&& __lhs, _T2&& __rhs) const {
+ return std::__invoke(__pred,
+ std::__invoke(__proj, std::forward<_T1>(__lhs)),
+ std::__invoke(__proj, std::forward<_T2>(__rhs)));
+ }
+
+};
+
+template <class _Pred, class _Proj, class = void>
+struct __can_use_pristine_comp : false_type {};
+
+template <class _Pred, class _Proj>
+struct __can_use_pristine_comp<_Pred, _Proj, __enable_if_t<
+ !is_member_pointer<typename decay<_Pred>::type>::value && (
+#if _LIBCPP_STD_VER > 17
+ is_same<typename decay<_Proj>::type, identity>::value ||
+#endif
+ is_same<typename decay<_Proj>::type, __identity>::value
+ )
+> > : true_type {};
+
+template <class _Pred, class _Proj>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
+__enable_if_t<
+ !__can_use_pristine_comp<_Pred, _Proj>::value,
+ _ProjectedPred<_Pred, _Proj>
+>
+__make_projected(_Pred& __pred, _Proj& __proj) {
+ return _ProjectedPred<_Pred, _Proj>(__pred, __proj);
+}
+
+// Avoid creating the functor and just use the pristine comparator -- for certain algorithms, this would enable
+// optimizations that rely on the type of the comparator. Additionally, this results in less layers of indirection in
+// the call stack when the comparator is invoked, even in an unoptimized build.
+template <class _Pred, class _Proj>
+_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR static
+__enable_if_t<
+ __can_use_pristine_comp<_Pred, _Proj>::value,
+ _Pred&
+>
+__make_projected(_Pred& __pred, _Proj&) {
+ return __pred;
+}
+
+_LIBCPP_END_NAMESPACE_STD
+
#if _LIBCPP_STD_VER > 17 && !defined(_LIBCPP_HAS_NO_INCOMPLETE_RANGES)
_LIBCPP_BEGIN_NAMESPACE_STD
namespace ranges {
-template <class _Pred, class _Proj>
-_LIBCPP_HIDE_FROM_ABI constexpr static
-decltype(auto) __make_projected_pred(_Pred& __pred, _Proj& __proj) {
- if constexpr (same_as<decay_t<_Proj>, identity> && !is_member_pointer_v<decay_t<_Pred>>) {
- // Avoid creating the lambda and just use the pristine predicate -- for certain algorithms, this would enable
- // optimizations that rely on the type of the predicate.
- return __pred;
-
- } else {
- return [&](auto&& __x) {
- return std::invoke(__pred, std::invoke(__proj, std::forward<decltype(__x)>(__x)));
- };
- }
-}
-
-template <class _Comp, class _Proj>
-_LIBCPP_HIDE_FROM_ABI constexpr static
-decltype(auto) __make_projected_comp(_Comp& __comp, _Proj& __proj) {
- if constexpr (same_as<decay_t<_Proj>, identity> && !is_member_pointer_v<decay_t<_Comp>>) {
- // Avoid creating the lambda and just use the pristine comparator -- for certain algorithms, this would enable
- // optimizations that rely on the type of the comparator.
- return __comp;
-
- } else {
- return [&](auto&& __lhs, auto&& __rhs) {
- return std::invoke(__comp,
- std::invoke(__proj, std::forward<decltype(__lhs)>(__lhs)),
- std::invoke(__proj, std::forward<decltype(__rhs)>(__rhs)));
- };
- }
-}
-
template <class _Comp, class _Proj1, class _Proj2>
_LIBCPP_HIDE_FROM_ABI constexpr static
decltype(auto) __make_projected_comp(_Comp& __comp, _Proj1& __proj1, _Proj2& __proj2) {
diff --git a/include/__algorithm/partial_sort.h b/include/__algorithm/partial_sort.h
index 24016e5..dff0cd0 100644
--- a/include/__algorithm/partial_sort.h
+++ b/include/__algorithm/partial_sort.h
@@ -31,12 +31,12 @@
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
_LIBCPP_CONSTEXPR_AFTER_CXX17
_RandomAccessIterator __partial_sort_impl(
- _RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare __comp) {
+ _RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) {
if (__first == __middle) {
return _IterOps<_AlgPolicy>::next(__middle, __last);
}
- std::__make_heap<_AlgPolicy, _Compare>(__first, __middle, __comp);
+ std::__make_heap<_AlgPolicy>(__first, __middle, __comp);
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
_RandomAccessIterator __i = __middle;
@@ -45,11 +45,11 @@
if (__comp(*__i, *__first))
{
_IterOps<_AlgPolicy>::iter_swap(__i, __first);
- std::__sift_down<_AlgPolicy, _Compare>(__first, __comp, __len, __first);
+ std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
}
}
- std::__sort_heap<_AlgPolicy, _Compare>(std::move(__first), std::move(__middle), __comp);
+ std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
return __i;
}
@@ -64,7 +64,7 @@
std::__debug_randomize_range<_AlgPolicy>(__first, __last);
using _Comp_ref = typename __comp_ref_type<_Compare>::type;
- auto __last_iter = std::__partial_sort_impl<_AlgPolicy, _Comp_ref>(__first, __middle, __last, __comp);
+ auto __last_iter = std::__partial_sort_impl<_AlgPolicy>(__first, __middle, __last, static_cast<_Comp_ref>(__comp));
std::__debug_randomize_range<_AlgPolicy>(__middle, __last);
diff --git a/include/__algorithm/partial_sort_copy.h b/include/__algorithm/partial_sort_copy.h
index 3556764..55edf31 100644
--- a/include/__algorithm/partial_sort_copy.h
+++ b/include/__algorithm/partial_sort_copy.h
@@ -13,10 +13,16 @@
#include <__algorithm/comp_ref_type.h>
#include <__algorithm/iterator_operations.h>
#include <__algorithm/make_heap.h>
+#include <__algorithm/make_projected.h>
#include <__algorithm/sift_down.h>
#include <__algorithm/sort_heap.h>
#include <__config>
+#include <__functional/identity.h>
+#include <__functional/invoke.h>
#include <__iterator/iterator_traits.h>
+#include <__type_traits/is_callable.h>
+#include <__utility/move.h>
+#include <__utility/pair.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -24,27 +30,33 @@
_LIBCPP_BEGIN_NAMESPACE_STD
-template <class _AlgPolicy, class _Compare, class _InputIterator, class _RandomAccessIterator>
-_LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator
-__partial_sort_copy(_InputIterator __first, _InputIterator __last,
- _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
+template <class _AlgPolicy, class _Compare,
+ class _InputIterator, class _Sentinel1, class _RandomAccessIterator, class _Sentinel2,
+ class _Proj1, class _Proj2>
+_LIBCPP_CONSTEXPR_AFTER_CXX17 pair<_InputIterator, _RandomAccessIterator>
+__partial_sort_copy(_InputIterator __first, _Sentinel1 __last,
+ _RandomAccessIterator __result_first, _Sentinel2 __result_last,
+ _Compare&& __comp, _Proj1&& __proj1, _Proj2&& __proj2)
{
_RandomAccessIterator __r = __result_first;
+ auto&& __projected_comp = std::__make_projected(__comp, __proj2);
+
if (__r != __result_last)
{
for (; __first != __last && __r != __result_last; ++__first, (void) ++__r)
*__r = *__first;
- std::__make_heap<_AlgPolicy, _Compare>(__result_first, __r, __comp);
+ std::__make_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first;
for (; __first != __last; ++__first)
- if (__comp(*__first, *__result_first))
- {
+ if (std::__invoke(__comp, std::__invoke(__proj1, *__first), std::__invoke(__proj2, *__result_first))) {
*__result_first = *__first;
- std::__sift_down<_AlgPolicy, _Compare>(__result_first, __comp, __len, __result_first);
+ std::__sift_down<_AlgPolicy>(__result_first, __projected_comp, __len, __result_first);
}
- std::__sort_heap<_AlgPolicy, _Compare>(__result_first, __r, __comp);
+ std::__sort_heap<_AlgPolicy>(__result_first, __r, __projected_comp);
}
- return __r;
+
+ return pair<_InputIterator, _RandomAccessIterator>(
+ _IterOps<_AlgPolicy>::next(std::move(__first), std::move(__last)), std::move(__r));
}
template <class _InputIterator, class _RandomAccessIterator, class _Compare>
@@ -53,9 +65,13 @@
partial_sort_copy(_InputIterator __first, _InputIterator __last,
_RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp)
{
- typedef typename __comp_ref_type<_Compare>::type _Comp_ref;
- return std::__partial_sort_copy<_ClassicAlgPolicy, _Comp_ref>(
- __first, __last, __result_first, __result_last, __comp);
+ static_assert(__is_callable<_Compare, decltype(*__first), decltype(*__result_first)>::value,
+ "Comparator has to be callable");
+
+ using _Comp_ref = typename __comp_ref_type<_Compare>::type;
+ auto __result = std::__partial_sort_copy<_ClassicAlgPolicy>(__first, __last, __result_first, __result_last,
+ static_cast<_Comp_ref>(__comp), __identity(), __identity());
+ return __result.second;
}
template <class _InputIterator, class _RandomAccessIterator>
diff --git a/include/__algorithm/pop_heap.h b/include/__algorithm/pop_heap.h
index 870af50..44d5d39 100644
--- a/include/__algorithm/pop_heap.h
+++ b/include/__algorithm/pop_heap.h
@@ -38,7 +38,7 @@
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
if (__len > 1) {
value_type __top = _IterOps<_AlgPolicy>::__iter_move(__first); // create a hole at __first
- _RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy, _CompRef>(__first, __comp_ref, __len);
+ _RandomAccessIterator __hole = std::__floyd_sift_down<_AlgPolicy>(__first, __comp_ref, __len);
--__last;
if (__hole == __last) {
@@ -47,7 +47,7 @@
*__hole = _IterOps<_AlgPolicy>::__iter_move(__last);
++__hole;
*__last = std::move(__top);
- std::__sift_up<_AlgPolicy, _CompRef>(__first, __hole, __comp_ref, __hole - __first);
+ std::__sift_up<_AlgPolicy>(__first, __hole, __comp_ref, __hole - __first);
}
}
}
diff --git a/include/__algorithm/push_heap.h b/include/__algorithm/push_heap.h
index 716670b..72ad51e 100644
--- a/include/__algorithm/push_heap.h
+++ b/include/__algorithm/push_heap.h
@@ -25,7 +25,7 @@
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
-void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
+void __sift_up(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
using value_type = typename iterator_traits<_RandomAccessIterator>::value_type;
diff --git a/include/__algorithm/ranges_inplace_merge.h b/include/__algorithm/ranges_inplace_merge.h
index 2152e66..12c9090 100644
--- a/include/__algorithm/ranges_inplace_merge.h
+++ b/include/__algorithm/ranges_inplace_merge.h
@@ -44,7 +44,7 @@
__inplace_merge_impl(_Iter __first, _Iter __middle, _Sent __last, _Comp&& __comp, _Proj&& __proj) {
auto __last_iter = ranges::next(__middle, __last);
std::__inplace_merge<_RangeAlgPolicy>(
- std::move(__first), std::move(__middle), __last_iter, ranges::__make_projected_comp(__comp, __proj));
+ std::move(__first), std::move(__middle), __last_iter, std::__make_projected(__comp, __proj));
return __last_iter;
}
diff --git a/include/__algorithm/ranges_is_heap.h b/include/__algorithm/ranges_is_heap.h
index a3e86d1..0bb1dcd 100644
--- a/include/__algorithm/ranges_is_heap.h
+++ b/include/__algorithm/ranges_is_heap.h
@@ -39,7 +39,7 @@
_LIBCPP_HIDE_FROM_ABI constexpr
static bool __is_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
auto __last_iter = ranges::next(__first, __last);
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ auto&& __projected_comp = std::__make_projected(__comp, __proj);
auto __result = std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp);
return __result == __last;
diff --git a/include/__algorithm/ranges_is_heap_until.h b/include/__algorithm/ranges_is_heap_until.h
index bcd33ad..8a751fc 100644
--- a/include/__algorithm/ranges_is_heap_until.h
+++ b/include/__algorithm/ranges_is_heap_until.h
@@ -40,7 +40,7 @@
_LIBCPP_HIDE_FROM_ABI constexpr
static _Iter __is_heap_until_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
auto __last_iter = ranges::next(__first, __last);
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ auto&& __projected_comp = std::__make_projected(__comp, __proj);
return std::__is_heap_until(std::move(__first), std::move(__last_iter), __projected_comp);
}
diff --git a/include/__algorithm/ranges_make_heap.h b/include/__algorithm/ranges_make_heap.h
index 8eabdd1..b114286 100644
--- a/include/__algorithm/ranges_make_heap.h
+++ b/include/__algorithm/ranges_make_heap.h
@@ -45,7 +45,7 @@
_Iter __make_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
auto __last_iter = ranges::next(__first, __last);
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ auto&& __projected_comp = std::__make_projected(__comp, __proj);
std::__make_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
return __last_iter;
diff --git a/include/__algorithm/ranges_nth_element.h b/include/__algorithm/ranges_nth_element.h
index b15eb81..ad63bd2 100644
--- a/include/__algorithm/ranges_nth_element.h
+++ b/include/__algorithm/ranges_nth_element.h
@@ -44,7 +44,7 @@
_Iter __nth_element_fn_impl(_Iter __first, _Iter __nth, _Sent __last, _Comp& __comp, _Proj& __proj) {
auto __last_iter = ranges::next(__first, __last);
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ auto&& __projected_comp = std::__make_projected(__comp, __proj);
std::__nth_element_impl<_RangeAlgPolicy>(std::move(__first), std::move(__nth), __last_iter, __projected_comp);
return __last_iter;
diff --git a/include/__algorithm/ranges_partial_sort.h b/include/__algorithm/ranges_partial_sort.h
index 5e82bc6..020e349 100644
--- a/include/__algorithm/ranges_partial_sort.h
+++ b/include/__algorithm/ranges_partial_sort.h
@@ -43,7 +43,7 @@
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) {
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __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/include/__algorithm/ranges_partial_sort_copy.h b/include/__algorithm/ranges_partial_sort_copy.h
index 55ad2ca..271c347 100644
--- a/include/__algorithm/ranges_partial_sort_copy.h
+++ b/include/__algorithm/ranges_partial_sort_copy.h
@@ -10,11 +10,11 @@
#define _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H
#include <__algorithm/in_out_result.h>
+#include <__algorithm/iterator_operations.h>
#include <__algorithm/make_projected.h>
#include <__algorithm/partial_sort_copy.h>
#include <__config>
#include <__functional/identity.h>
-#include <__functional/invoke.h>
#include <__functional/ranges_operations.h>
#include <__iterator/concepts.h>
#include <__iterator/iterator_traits.h>
@@ -23,7 +23,6 @@
#include <__ranges/access.h>
#include <__ranges/concepts.h>
#include <__ranges/dangling.h>
-#include <__utility/forward.h>
#include <__utility/move.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -52,9 +51,11 @@
partial_sort_copy_result<_Iter1, _Iter2>
operator()(_Iter1 __first, _Sent1 __last, _Iter2 __result_first, _Sent2 __result_last,
_Comp __comp = {}, _Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
- // TODO: implement
- (void)__first; (void)__last; (void)__result_first; (void)__result_last; (void)__comp; (void)__proj1; (void)__proj2;
- return {};
+ auto __result = std::__partial_sort_copy<_RangeAlgPolicy>(
+ std::move(__first), std::move(__last), std::move(__result_first), std::move(__result_last),
+ __comp, __proj1, __proj2
+ );
+ return {std::move(__result.first), std::move(__result.second)};
}
template <input_range _Range1, random_access_range _Range2, class _Comp = ranges::less,
@@ -67,9 +68,11 @@
partial_sort_copy_result<borrowed_iterator_t<_Range1>, borrowed_iterator_t<_Range2>>
operator()(_Range1&& __range, _Range2&& __result_range, _Comp __comp = {},
_Proj1 __proj1 = {}, _Proj2 __proj2 = {}) const {
- // TODO: implement
- (void)__range; (void)__result_range; (void)__comp; (void)__proj1; (void)__proj2;
- return {};
+ auto __result = std::__partial_sort_copy<_RangeAlgPolicy>(
+ ranges::begin(__range), ranges::end(__range), ranges::begin(__result_range), ranges::end(__result_range),
+ __comp, __proj1, __proj2
+ );
+ return {std::move(__result.first), std::move(__result.second)};
}
};
diff --git a/include/__algorithm/ranges_partition.h b/include/__algorithm/ranges_partition.h
index 60bee69..6a53933 100644
--- a/include/__algorithm/ranges_partition.h
+++ b/include/__algorithm/ranges_partition.h
@@ -44,7 +44,7 @@
template <class _Iter, class _Sent, class _Proj, class _Pred>
_LIBCPP_HIDE_FROM_ABI static constexpr
subrange<__uncvref_t<_Iter>> __partition_fn_impl(_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
- auto&& __projected_pred = ranges::__make_projected_pred(__pred, __proj);
+ auto&& __projected_pred = std::__make_projected(__pred, __proj);
auto __result = std::__partition<_RangeAlgPolicy>(
std::move(__first), std::move(__last), __projected_pred, __iterator_concept<_Iter>());
diff --git a/include/__algorithm/ranges_pop_heap.h b/include/__algorithm/ranges_pop_heap.h
index 92df611..fc7554f 100644
--- a/include/__algorithm/ranges_pop_heap.h
+++ b/include/__algorithm/ranges_pop_heap.h
@@ -46,7 +46,7 @@
auto __last_iter = ranges::next(__first, __last);
auto __len = __last_iter - __first;
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ auto&& __projected_comp = std::__make_projected(__comp, __proj);
std::__pop_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp, __len);
return __last_iter;
diff --git a/include/__algorithm/ranges_push_heap.h b/include/__algorithm/ranges_push_heap.h
index 4c41b00..3436b39 100644
--- a/include/__algorithm/ranges_push_heap.h
+++ b/include/__algorithm/ranges_push_heap.h
@@ -45,7 +45,7 @@
_Iter __push_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
auto __last_iter = ranges::next(__first, __last);
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ auto&& __projected_comp = std::__make_projected(__comp, __proj);
std::__push_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
return __last_iter;
diff --git a/include/__algorithm/ranges_sort.h b/include/__algorithm/ranges_sort.h
index ef14db6..c3f3cbf 100644
--- a/include/__algorithm/ranges_sort.h
+++ b/include/__algorithm/ranges_sort.h
@@ -44,7 +44,7 @@
_Iter __sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
auto __last_iter = ranges::next(__first, __last);
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ auto&& __projected_comp = std::__make_projected(__comp, __proj);
std::__sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
return __last_iter;
diff --git a/include/__algorithm/ranges_sort_heap.h b/include/__algorithm/ranges_sort_heap.h
index eb6a30d..f6e4dcb 100644
--- a/include/__algorithm/ranges_sort_heap.h
+++ b/include/__algorithm/ranges_sort_heap.h
@@ -45,7 +45,7 @@
_Iter __sort_heap_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
auto __last_iter = ranges::next(__first, __last);
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ auto&& __projected_comp = std::__make_projected(__comp, __proj);
std::__sort_heap<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
return __last_iter;
diff --git a/include/__algorithm/ranges_stable_partition.h b/include/__algorithm/ranges_stable_partition.h
index 27957db..b20dfa3 100644
--- a/include/__algorithm/ranges_stable_partition.h
+++ b/include/__algorithm/ranges_stable_partition.h
@@ -49,7 +49,7 @@
_Iter&& __first, _Sent&& __last, _Pred&& __pred, _Proj&& __proj) {
auto __last_iter = ranges::next(__first, __last);
- auto&& __projected_pred = ranges::__make_projected_pred(__pred, __proj);
+ auto&& __projected_pred = std::__make_projected(__pred, __proj);
auto __result = std::__stable_partition<_RangeAlgPolicy>(
std::move(__first), __last_iter, __projected_pred, __iterator_concept<_Iter>());
diff --git a/include/__algorithm/ranges_stable_sort.h b/include/__algorithm/ranges_stable_sort.h
index de48416..7ecffef 100644
--- a/include/__algorithm/ranges_stable_sort.h
+++ b/include/__algorithm/ranges_stable_sort.h
@@ -44,7 +44,7 @@
static _Iter __stable_sort_fn_impl(_Iter __first, _Sent __last, _Comp& __comp, _Proj& __proj) {
auto __last_iter = ranges::next(__first, __last);
- auto&& __projected_comp = ranges::__make_projected_comp(__comp, __proj);
+ auto&& __projected_comp = std::__make_projected(__comp, __proj);
std::__stable_sort_impl<_RangeAlgPolicy>(std::move(__first), __last_iter, __projected_comp);
return __last_iter;
diff --git a/include/__algorithm/ranges_unique.h b/include/__algorithm/ranges_unique.h
index 8518528..11370ae 100644
--- a/include/__algorithm/ranges_unique.h
+++ b/include/__algorithm/ranges_unique.h
@@ -47,7 +47,7 @@
_LIBCPP_HIDE_FROM_ABI constexpr subrange<_Iter>
operator()(_Iter __first, _Sent __last, _Comp __comp = {}, _Proj __proj = {}) const {
auto __ret = std::__unique<_RangeAlgPolicy>(
- std::move(__first), std::move(__last), ranges::__make_projected_comp(__comp, __proj));
+ std::move(__first), std::move(__last), std::__make_projected(__comp, __proj));
return {std::move(__ret.first), std::move(__ret.second)};
}
@@ -59,7 +59,7 @@
_LIBCPP_HIDE_FROM_ABI constexpr borrowed_subrange_t<_Range>
operator()(_Range&& __range, _Comp __comp = {}, _Proj __proj = {}) const {
auto __ret = std::__unique<_RangeAlgPolicy>(
- ranges::begin(__range), ranges::end(__range), ranges::__make_projected_comp(__comp, __proj));
+ ranges::begin(__range), ranges::end(__range), std::__make_projected(__comp, __proj));
return {std::move(__ret.first), std::move(__ret.second)};
}
};
diff --git a/include/__algorithm/ranges_unique_copy.h b/include/__algorithm/ranges_unique_copy.h
index d047b44..8c0b970 100644
--- a/include/__algorithm/ranges_unique_copy.h
+++ b/include/__algorithm/ranges_unique_copy.h
@@ -76,7 +76,7 @@
std::move(__first),
std::move(__last),
std::move(__result),
- __make_projected_comp(__comp, __proj),
+ std::__make_projected(__comp, __proj),
__algo_tag_t<_InIter, _OutIter>());
return {std::move(__ret.first), std::move(__ret.second)};
}
@@ -95,7 +95,7 @@
ranges::begin(__range),
ranges::end(__range),
std::move(__result),
- __make_projected_comp(__comp, __proj),
+ std::__make_projected(__comp, __proj),
__algo_tag_t<iterator_t<_Range>, _OutIter>());
return {std::move(__ret.first), std::move(__ret.second)};
}
diff --git a/include/__algorithm/sift_down.h b/include/__algorithm/sift_down.h
index be2eb29..0681123 100644
--- a/include/__algorithm/sift_down.h
+++ b/include/__algorithm/sift_down.h
@@ -23,7 +23,7 @@
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_CONSTEXPR_AFTER_CXX11 void
-__sift_down(_RandomAccessIterator __first, _Compare __comp,
+__sift_down(_RandomAccessIterator __first, _Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len,
_RandomAccessIterator __start)
{
@@ -79,7 +79,7 @@
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
_LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator
-__floyd_sift_down(_RandomAccessIterator __first, _Compare __comp,
+__floyd_sift_down(_RandomAccessIterator __first, _Compare&& __comp,
typename iterator_traits<_RandomAccessIterator>::difference_type __len)
{
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
diff --git a/include/__algorithm/sort_heap.h b/include/__algorithm/sort_heap.h
index b9f0b2c..7713b76 100644
--- a/include/__algorithm/sort_heap.h
+++ b/include/__algorithm/sort_heap.h
@@ -26,13 +26,13 @@
template <class _AlgPolicy, class _Compare, class _RandomAccessIterator>
inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX11
-void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare& __comp) {
+void __sort_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare&& __comp) {
using _CompRef = typename __comp_ref_type<_Compare>::type;
_CompRef __comp_ref = __comp;
using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
for (difference_type __n = __last - __first; __n > 1; --__last, (void) --__n)
- std::__pop_heap<_AlgPolicy, _CompRef>(__first, __last, __comp_ref, __n);
+ std::__pop_heap<_AlgPolicy>(__first, __last, __comp_ref, __n);
}
template <class _RandomAccessIterator, class _Compare>
diff --git a/include/algorithm b/include/algorithm
index 7b510b5..92e9327 100644
--- a/include/algorithm
+++ b/include/algorithm
@@ -446,6 +446,25 @@
indirect_unary_predicate<projected<iterator_t<R>, Proj>> Pred>
constexpr bool ranges::none_of(R&& r, Pred pred, Proj proj = {}); // since C++20
+ template<input_iterator I1, sentinel_for<I1> S1,
+ random_access_iterator I2, sentinel_for<I2> S2,
+ class Comp = ranges::less, class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_copyable<I1, I2> && sortable<I2, Comp, Proj2> &&
+ indirect_strict_weak_order<Comp, projected<I1, Proj1>, projected<I2, Proj2>>
+ constexpr partial_sort_copy_result<I1, I2>
+ partial_sort_copy(I1 first, S1 last, I2 result_first, S2 result_last,
+ Comp comp = {}, Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
+
+ template<input_range R1, random_access_range R2, class Comp = ranges::less,
+ class Proj1 = identity, class Proj2 = identity>
+ requires indirectly_copyable<iterator_t<R1>, iterator_t<R2>> &&
+ sortable<iterator_t<R2>, Comp, Proj2> &&
+ indirect_strict_weak_order<Comp, projected<iterator_t<R1>, Proj1>,
+ projected<iterator_t<R2>, Proj2>>
+ constexpr partial_sort_copy_result<borrowed_iterator_t<R1>, borrowed_iterator_t<R2>>
+ partial_sort_copy(R1&& r, R2&& result_r, Comp comp = {},
+ Proj1 proj1 = {}, Proj2 proj2 = {}); // Since C++20
+
template<forward_iterator I, sentinel_for<I> S, class Proj = identity,
indirect_strict_weak_order<projected<I, Proj>> Comp = ranges::less>
constexpr bool ranges::is_sorted(I first, S last, Comp comp = {}, Proj proj = {}); // since C++20
@@ -1668,6 +1687,7 @@
#include <__algorithm/ranges_none_of.h>
#include <__algorithm/ranges_nth_element.h>
#include <__algorithm/ranges_partial_sort.h>
+#include <__algorithm/ranges_partial_sort_copy.h>
#include <__algorithm/ranges_partition.h>
#include <__algorithm/ranges_partition_copy.h>
#include <__algorithm/ranges_partition_point.h>