1 //===----------------------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H 10 #define _LIBCPP___ALGORITHM_PARTIAL_SORT_H 11 12 #include <__config> 13 #include <__algorithm/comp_ref_type.h> 14 #include <__algorithm/make_heap.h> 15 #include <__algorithm/sift_down.h> 16 #include <__algorithm/sort_heap.h> 17 #include <__iterator/iterator_traits.h> 18 19 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 20 #pragma GCC system_header 21 #endif 22 23 _LIBCPP_PUSH_MACROS 24 #include <__undef_macros> 25 26 _LIBCPP_BEGIN_NAMESPACE_STD 27 28 template <class _Compare, class _RandomAccessIterator> 29 _LIBCPP_CONSTEXPR_AFTER_CXX17 void 30 __partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 31 _Compare __comp) 32 { 33 _VSTD::__make_heap<_Compare>(__first, __middle, __comp); 34 typename iterator_traits<_RandomAccessIterator>::difference_type __len = __middle - __first; 35 for (_RandomAccessIterator __i = __middle; __i != __last; ++__i) 36 { 37 if (__comp(*__i, *__first)) 38 { 39 swap(*__i, *__first); 40 _VSTD::__sift_down<_Compare>(__first, __middle, __comp, __len, __first); 41 } 42 } 43 _VSTD::__sort_heap<_Compare>(__first, __middle, __comp); 44 } 45 46 template <class _RandomAccessIterator, class _Compare> 47 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 48 void 49 partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last, 50 _Compare __comp) 51 { 52 typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 53 _VSTD::__partial_sort<_Comp_ref>(__first, __middle, __last, __comp); 54 } 55 56 template <class _RandomAccessIterator> 57 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 58 void 59 partial_sort(_RandomAccessIterator __first, _RandomAccessIterator __middle, _RandomAccessIterator __last) 60 { 61 _VSTD::partial_sort(__first, __middle, __last, 62 __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 63 } 64 65 // partial_sort_copy 66 67 template <class _Compare, class _InputIterator, class _RandomAccessIterator> 68 _LIBCPP_CONSTEXPR_AFTER_CXX17 _RandomAccessIterator 69 __partial_sort_copy(_InputIterator __first, _InputIterator __last, 70 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) 71 { 72 _RandomAccessIterator __r = __result_first; 73 if (__r != __result_last) 74 { 75 for (; __first != __last && __r != __result_last; ++__first, (void) ++__r) 76 *__r = *__first; 77 _VSTD::__make_heap<_Compare>(__result_first, __r, __comp); 78 typename iterator_traits<_RandomAccessIterator>::difference_type __len = __r - __result_first; 79 for (; __first != __last; ++__first) 80 if (__comp(*__first, *__result_first)) 81 { 82 *__result_first = *__first; 83 _VSTD::__sift_down<_Compare>(__result_first, __r, __comp, __len, __result_first); 84 } 85 _VSTD::__sort_heap<_Compare>(__result_first, __r, __comp); 86 } 87 return __r; 88 } 89 90 template <class _InputIterator, class _RandomAccessIterator, class _Compare> 91 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 92 _RandomAccessIterator 93 partial_sort_copy(_InputIterator __first, _InputIterator __last, 94 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last, _Compare __comp) 95 { 96 typedef typename __comp_ref_type<_Compare>::type _Comp_ref; 97 return _VSTD::__partial_sort_copy<_Comp_ref>(__first, __last, __result_first, __result_last, __comp); 98 } 99 100 template <class _InputIterator, class _RandomAccessIterator> 101 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17 102 _RandomAccessIterator 103 partial_sort_copy(_InputIterator __first, _InputIterator __last, 104 _RandomAccessIterator __result_first, _RandomAccessIterator __result_last) 105 { 106 return _VSTD::partial_sort_copy(__first, __last, __result_first, __result_last, 107 __less<typename iterator_traits<_RandomAccessIterator>::value_type>()); 108 } 109 110 _LIBCPP_END_NAMESPACE_STD 111 112 _LIBCPP_POP_MACROS 113 114 #endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H 115