@@ -29,37 +29,39 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void
2929__sift_down (_RandomAccessIterator __first,
3030 _Compare&& __comp,
3131 typename iterator_traits<_RandomAccessIterator>::difference_type __len,
32- _RandomAccessIterator __start) {
32+ typename iterator_traits< _RandomAccessIterator>::difference_type __start) {
3333 using _Ops = _IterOps<_AlgPolicy>;
3434
3535 typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
3636 typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type;
37- // left-child of __start is at 2 * __start + 1
38- // right-child of __start is at 2 * __start + 2
39- difference_type __child = __start - __first;
4037
41- if (__len < 2 || (__len - 2 ) / 2 < __child )
38+ if (__len < 2 )
4239 return ;
4340
44- __child = 2 * __child + 1 ;
45- _RandomAccessIterator __child_i = __first + __child;
41+ // left-child of __start is at 2 * __start + 1
42+ // right-child of __start is at 2 * __start + 2
43+ difference_type __child = 2 * (__start - __first) + 1 ;
44+ _RandomAccessIterator __child_i = __first + __child, __start_i = __first + __start;
4645
47- if ((__child + 1 ) < __len && __comp (*__child_i, *(__child_i + difference_type (1 )))) {
48- // right-child exists and is greater than left-child
49- ++__child_i;
50- ++__child;
46+ if ((__child + 1 ) < __len) {
47+ _RandomAccessIterator __right_i = _Ops::next (__child_i);
48+ if (__comp (*__child_i, *__right_i)) {
49+ // right-child exists and is greater than left-child
50+ __child_i = __right_i;
51+ ++__child;
52+ }
5153 }
5254
5355 // check if we are in heap-order
54- if (__comp (*__child_i, *__start ))
56+ if (__comp (*__child_i, *__start_i ))
5557 // we are, __start is larger than its largest child
5658 return ;
5759
58- value_type __top (_Ops::__iter_move (__start ));
60+ value_type __top (_Ops::__iter_move (__start_i ));
5961 do {
6062 // we are not in heap-order, swap the parent with its largest child
61- *__start = _Ops::__iter_move (__child_i);
62- __start = __child_i;
63+ *__start_i = _Ops::__iter_move (__child_i);
64+ __start_i = __child_i;
6365
6466 if ((__len - 2 ) / 2 < __child)
6567 break ;
@@ -68,45 +70,53 @@ __sift_down(_RandomAccessIterator __first,
6870 __child = 2 * __child + 1 ;
6971 __child_i = __first + __child;
7072
71- if ((__child + 1 ) < __len && __comp (*__child_i, *(__child_i + difference_type (1 )))) {
72- // right-child exists and is greater than left-child
73- ++__child_i;
74- ++__child;
73+ if ((__child + 1 ) < __len) {
74+ _RandomAccessIterator __right_i = _Ops::next (__child_i);
75+ if (__comp (*__child_i, *__right_i)) {
76+ // right-child exists and is greater than left-child
77+ __child_i = __right_i;
78+ ++__child;
79+ }
7580 }
7681
7782 // check if we are in heap-order
7883 } while (!__comp (*__child_i, __top));
79- *__start = std::move (__top);
84+ *__start_i = std::move (__top);
8085}
8186
8287template <class _AlgPolicy , class _Compare , class _RandomAccessIterator >
8388_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _RandomAccessIterator __floyd_sift_down (
8489 _RandomAccessIterator __first,
8590 _Compare&& __comp,
8691 typename iterator_traits<_RandomAccessIterator>::difference_type __len) {
87- using difference_type = typename iterator_traits<_RandomAccessIterator>::difference_type;
88- _LIBCPP_ASSERT_INTERNAL (__len >= 2 , " shouldn't be called unless __len >= 2" );
92+ _LIBCPP_ASSERT_INTERNAL (__len > 1 , " shouldn't be called unless __len > 1" );
8993
90- _RandomAccessIterator __hole = __first;
91- _RandomAccessIterator __child_i = __first;
92- difference_type __child = 0 ;
94+ using _Ops = _IterOps<_AlgPolicy>;
9395
94- while (true ) {
95- __child_i += difference_type (__child + 1 );
96- __child = 2 * __child + 1 ;
96+ typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
9797
98- if ((__child + 1 ) < __len && __comp (*__child_i, *(__child_i + difference_type (1 )))) {
99- // right-child exists and is greater than left-child
100- ++__child_i;
101- ++__child;
98+ difference_type __child = 1 ;
99+ _RandomAccessIterator __hole = __first, __child_i = __first;
100+
101+ while (true ) {
102+ __child_i += __child;
103+ __child *= 2 ;
104+
105+ if (__child < __len) {
106+ _RandomAccessIterator __right_i = _Ops::next (__child_i);
107+ if (__comp (*__child_i, *__right_i)) {
108+ // right-child exists and is greater than left-child
109+ __child_i = __right_i;
110+ ++__child;
111+ }
102112 }
103113
104114 // swap __hole with its largest child
105- *__hole = _IterOps<_AlgPolicy> ::__iter_move (__child_i);
115+ *__hole = _Ops ::__iter_move (__child_i);
106116 __hole = __child_i;
107117
108118 // if __hole is now a leaf, we're done
109- if (__child > ( __len - 2 ) / 2 )
119+ if (__child > __len / 2 )
110120 return __hole;
111121 }
112122}
0 commit comments