1134723edSLouis Dionne //===----------------------------------------------------------------------===//
2134723edSLouis Dionne //
3134723edSLouis Dionne // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4134723edSLouis Dionne // See https://llvm.org/LICENSE.txt for license information.
5134723edSLouis Dionne // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6134723edSLouis Dionne //
7134723edSLouis Dionne //===----------------------------------------------------------------------===//
8134723edSLouis Dionne
9134723edSLouis Dionne #ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H
10134723edSLouis Dionne #define _LIBCPP___ALGORITHM_PARTIAL_SORT_H
11134723edSLouis Dionne
12134723edSLouis Dionne #include <__algorithm/comp.h>
13134723edSLouis Dionne #include <__algorithm/comp_ref_type.h>
14a7c3379cSKonstantin Varlamov #include <__algorithm/iterator_operations.h>
15134723edSLouis Dionne #include <__algorithm/make_heap.h>
16134723edSLouis Dionne #include <__algorithm/sift_down.h>
17134723edSLouis Dionne #include <__algorithm/sort_heap.h>
184d81a46fSArthur O'Dwyer #include <__config>
19f3966eafSLouis Dionne #include <__debug>
202aea8af2SNikolas Klauser #include <__debug_utils/randomize_range.h>
21134723edSLouis Dionne #include <__iterator/iterator_traits.h>
225dd19adaSvarconst #include <__utility/move.h>
235dd19adaSvarconst #include <type_traits>
24134723edSLouis Dionne
25134723edSLouis Dionne #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
26134723edSLouis Dionne # pragma GCC system_header
27134723edSLouis Dionne #endif
28134723edSLouis Dionne
29134723edSLouis Dionne _LIBCPP_BEGIN_NAMESPACE_STD
30134723edSLouis Dionne
315dd19adaSvarconst template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
325dd19adaSvarconst _LIBCPP_CONSTEXPR_AFTER_CXX17
__partial_sort_impl(_RandomAccessIterator __first,_RandomAccessIterator __middle,_Sentinel __last,_Compare && __comp)335dd19adaSvarconst _RandomAccessIterator __partial_sort_impl(
34*2c766efcSKonstantin Varlamov _RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last, _Compare&& __comp) {
355dd19adaSvarconst if (__first == __middle) {
365dd19adaSvarconst return _IterOps<_AlgPolicy>::next(__middle, __last);
375dd19adaSvarconst }
385dd19adaSvarconst
39*2c766efcSKonstantin Varlamov std::__make_heap<_AlgPolicy>(__first, __middle, __comp);
405dd19adaSvarconst
41134723edSLouis Dionne typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first;
425dd19adaSvarconst _RandomAccessIterator __i = __middle;
435dd19adaSvarconst for (; __i != __last; ++__i)
44134723edSLouis Dionne {
45134723edSLouis Dionne if (__comp(*__i, *__first))
46134723edSLouis Dionne {
47a7c3379cSKonstantin Varlamov _IterOps<_AlgPolicy>::iter_swap(__i, __first);
48*2c766efcSKonstantin Varlamov std::__sift_down<_AlgPolicy>(__first, __comp, __len, __first);
49134723edSLouis Dionne }
505dd19adaSvarconst
51134723edSLouis Dionne }
52*2c766efcSKonstantin Varlamov std::__sort_heap<_AlgPolicy>(std::move(__first), std::move(__middle), __comp);
535dd19adaSvarconst
545dd19adaSvarconst return __i;
555dd19adaSvarconst }
565dd19adaSvarconst
575dd19adaSvarconst template <class _AlgPolicy, class _Compare, class _RandomAccessIterator, class _Sentinel>
585dd19adaSvarconst _LIBCPP_CONSTEXPR_AFTER_CXX17
__partial_sort(_RandomAccessIterator __first,_RandomAccessIterator __middle,_Sentinel __last,_Compare & __comp)595dd19adaSvarconst _RandomAccessIterator __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _Sentinel __last,
605dd19adaSvarconst _Compare& __comp) {
615dd19adaSvarconst if (__first == __middle)
625dd19adaSvarconst return _IterOps<_AlgPolicy>::next(__middle, __last);
635dd19adaSvarconst
6414cf74d6SKonstantin Varlamov std::__debug_randomize_range<_AlgPolicy>(__first, __last);
655dd19adaSvarconst
665dd19adaSvarconst using _Comp_ref = typename __comp_ref_type<_Compare>::type;
67*2c766efcSKonstantin Varlamov auto __last_iter = std::__partial_sort_impl<_AlgPolicy>(__first, __middle, __last, static_cast<_Comp_ref>(__comp));
685dd19adaSvarconst
6914cf74d6SKonstantin Varlamov std::__debug_randomize_range<_AlgPolicy>(__middle, __last);
705dd19adaSvarconst
715dd19adaSvarconst return __last_iter;
72134723edSLouis Dionne }
73134723edSLouis Dionne
74134723edSLouis Dionne template <class _RandomAccessIterator, class _Compare>
75134723edSLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
76134723edSLouis Dionne void
partial_sort(_RandomAccessIterator __first,_RandomAccessIterator __middle,_RandomAccessIterator __last,_Compare __comp)77134723edSLouis Dionne partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last,
78134723edSLouis Dionne _Compare __comp)
79134723edSLouis Dionne {
805dd19adaSvarconst static_assert(std::is_copy_constructible<_RandomAccessIterator>::value, "Iterators must be copy constructible.");
815dd19adaSvarconst static_assert(std::is_copy_assignable<_RandomAccessIterator>::value, "Iterators must be copy assignable.");
825dd19adaSvarconst
835dd19adaSvarconst (void)std::__partial_sort<_ClassicAlgPolicy>(std::move(__first), std::move(__middle), std::move(__last), __comp);
84134723edSLouis Dionne }
85134723edSLouis Dionne
86134723edSLouis Dionne template <class _RandomAccessIterator>
87134723edSLouis Dionne inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
88134723edSLouis Dionne void
partial_sort(_RandomAccessIterator __first,_RandomAccessIterator __middle,_RandomAccessIterator __last)89134723edSLouis Dionne partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last)
90134723edSLouis Dionne {
91134723edSLouis Dionne _VSTD::partial_sort(__first, __middle, __last,
92134723edSLouis Dionne __less<typename iterator_traits<_RandomAccessIterator>::value_type>());
93134723edSLouis Dionne }
94134723edSLouis Dionne
95134723edSLouis Dionne _LIBCPP_END_NAMESPACE_STD
96134723edSLouis Dionne
97134723edSLouis Dionne #endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H
98