diff --git a/libcxx/include/__algorithm/copy_n.h b/libcxx/include/__algorithm/copy_n.h --- a/libcxx/include/__algorithm/copy_n.h +++ b/libcxx/include/__algorithm/copy_n.h @@ -57,9 +57,10 @@ >::type copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { - typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; - _IntegralSize __n = __orig_n; - return _VSTD::copy(__first, __first + __n, __result); + typedef typename iterator_traits<_InputIterator>::difference_type difference_type; + typedef decltype(_VSTD::__convert_to_integral(__orig_n)) _IntegralSize; + _IntegralSize __n = __orig_n; + return _VSTD::copy(__first, __first + difference_type(__n), __result); } _LIBCPP_END_NAMESPACE_STD diff --git a/libcxx/include/__algorithm/find_end.h b/libcxx/include/__algorithm/find_end.h --- a/libcxx/include/__algorithm/find_end.h +++ b/libcxx/include/__algorithm/find_end.h @@ -95,14 +95,16 @@ _LIBCPP_CONSTEXPR_AFTER_CXX11 _RandomAccessIterator1 __find_end( _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __pred, random_access_iterator_tag, random_access_iterator_tag) { + typedef typename iterator_traits<_RandomAccessIterator1>::difference_type _D1; + typedef typename iterator_traits<_RandomAccessIterator2>::difference_type _D2; // Take advantage of knowing source and pattern lengths. Stop short when source is smaller than pattern - typename iterator_traits<_RandomAccessIterator2>::difference_type __len2 = __last2 - __first2; + _D2 __len2 = __last2 - __first2; if (__len2 == 0) return __last1; - typename iterator_traits<_RandomAccessIterator1>::difference_type __len1 = __last1 - __first1; + _D1 __len1 = __last1 - __first1; if (__len1 < __len2) return __last1; - const _RandomAccessIterator1 __s = __first1 + (__len2 - 1); // End of pattern match can't go before here + const _RandomAccessIterator1 __s = __first1 + _D1(__len2 - 1); // End of pattern match can't go before here _RandomAccessIterator1 __l1 = __last1; _RandomAccessIterator2 __l2 = __last2; --__l2; diff --git a/libcxx/include/__algorithm/make_heap.h b/libcxx/include/__algorithm/make_heap.h --- a/libcxx/include/__algorithm/make_heap.h +++ b/libcxx/include/__algorithm/make_heap.h @@ -30,9 +30,8 @@ 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) - { - _VSTD::__sift_down<_Compare>(__first, __last, __comp, __n, __first + __start); + for (difference_type __start = (__n - difference_type(2)) / 2; __start >= 0; --__start) { + _VSTD::__sift_down<_Compare>(__first, __last, __comp, __n, __first + __start); } } } diff --git a/libcxx/include/__algorithm/search.h b/libcxx/include/__algorithm/search.h --- a/libcxx/include/__algorithm/search.h +++ b/libcxx/include/__algorithm/search.h @@ -68,7 +68,7 @@ const _D1 __len1 = __last1 - __first1; if (__len1 < __len2) return _VSTD::make_pair(__last1, __last1); - const _RandomAccessIterator1 __s = __last1 - (__len2 - 1); // Start of pattern match can't go beyond here + const _RandomAccessIterator1 __s = __last1 - _D1(__len2 - 1); // Start of pattern match can't go beyond here while (true) { while (true) { @@ -83,7 +83,7 @@ _RandomAccessIterator2 __m2 = __first2; while (true) { if (++__m2 == __last2) - return _VSTD::make_pair(__first1, __first1 + __len2); + return _VSTD::make_pair(__first1, __first1 + _D1(__len2)); ++__m1; // no need to check range on __m1 because __s guarantees we have enough source if (!__pred(*__m1, *__m2)) { ++__first1; diff --git a/libcxx/include/__algorithm/search_n.h b/libcxx/include/__algorithm/search_n.h --- a/libcxx/include/__algorithm/search_n.h +++ b/libcxx/include/__algorithm/search_n.h @@ -59,12 +59,14 @@ _RandomAccessIterator __last, _Size __count, const _Tp& __value_, _BinaryPredicate __pred, random_access_iterator_tag) { + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; if (__count <= 0) return __first; _Size __len = static_cast<_Size>(__last - __first); if (__len < __count) return __last; - const _RandomAccessIterator __s = __last - (__count - 1); // Start of pattern match can't go beyond here + const _RandomAccessIterator __s = + __last - difference_type(__count - 1); // Start of pattern match can't go beyond here while (true) { // Find first element in sequence that matchs __value_, with a mininum of loop checks while (true) { diff --git a/libcxx/include/__algorithm/sift_down.h b/libcxx/include/__algorithm/sift_down.h --- a/libcxx/include/__algorithm/sift_down.h +++ b/libcxx/include/__algorithm/sift_down.h @@ -38,10 +38,10 @@ __child = 2 * __child + 1; _RandomAccessIterator __child_i = __first + __child; - if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { - // right-child exists and is greater than left-child - ++__child_i; - ++__child; + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; } // check if we are in heap-order @@ -63,10 +63,10 @@ __child = 2 * __child + 1; __child_i = __first + __child; - if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + 1))) { - // right-child exists and is greater than left-child - ++__child_i; - ++__child; + if ((__child + 1) < __len && __comp(*__child_i, *(__child_i + difference_type(1)))) { + // right-child exists and is greater than left-child + ++__child_i; + ++__child; } // check if we are in heap-order diff --git a/libcxx/include/__algorithm/sort.h b/libcxx/include/__algorithm/sort.h --- a/libcxx/include/__algorithm/sort.h +++ b/libcxx/include/__algorithm/sort.h @@ -156,72 +156,68 @@ void __insertion_sort_3(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - _RandomAccessIterator __j = __first+2; - _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp); - for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) - { - if (__comp(*__i, *__j)) - { - value_type __t(_VSTD::move(*__i)); - _RandomAccessIterator __k = __j; - __j = __i; - do - { - *__j = _VSTD::move(*__k); - __j = __k; - } while (__j != __first && __comp(__t, *--__k)); - *__j = _VSTD::move(__t); - } - __j = __i; + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; + _RandomAccessIterator __j = __first + difference_type(2); + _VSTD::__sort3<_Compare>(__first, __first + difference_type(1), __j, __comp); + for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { + if (__comp(*__i, *__j)) { + value_type __t(_VSTD::move(*__i)); + _RandomAccessIterator __k = __j; + __j = __i; + do { + *__j = _VSTD::move(*__k); + __j = __k; + } while (__j != __first && __comp(__t, *--__k)); + *__j = _VSTD::move(__t); } + __j = __i; + } } template bool __insertion_sort_incomplete(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp) { - switch (__last - __first) - { - case 0: - case 1: - return true; - case 2: - if (__comp(*--__last, *__first)) - swap(*__first, *__last); - return true; - case 3: - _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); - return true; - case 4: - _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); - return true; - case 5: - _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); - return true; - } + typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type; + switch (__last - __first) { + case 0: + case 1: + return true; + case 2: + if (__comp(*--__last, *__first)) + swap(*__first, *__last); + return true; + case 3: + _VSTD::__sort3<_Compare>(__first, __first + difference_type(1), --__last, __comp); + return true; + case 4: + _VSTD::__sort4<_Compare>(__first, __first + difference_type(1), __first + difference_type(2), --__last, __comp); + return true; + case 5: + _VSTD::__sort5<_Compare>(__first, __first + difference_type(1), __first + difference_type(2), + __first + difference_type(3), --__last, __comp); + return true; + } typedef typename iterator_traits<_RandomAccessIterator>::value_type value_type; - _RandomAccessIterator __j = __first+2; - _VSTD::__sort3<_Compare>(__first, __first+1, __j, __comp); + _RandomAccessIterator __j = __first + difference_type(2); + _VSTD::__sort3<_Compare>(__first, __first + difference_type(1), __j, __comp); const unsigned __limit = 8; unsigned __count = 0; - for (_RandomAccessIterator __i = __j+1; __i != __last; ++__i) - { - if (__comp(*__i, *__j)) - { - value_type __t(_VSTD::move(*__i)); - _RandomAccessIterator __k = __j; - __j = __i; - do - { - *__j = _VSTD::move(*__k); - __j = __k; - } while (__j != __first && __comp(__t, *--__k)); - *__j = _VSTD::move(__t); - if (++__count == __limit) - return ++__i == __last; - } + for (_RandomAccessIterator __i = __j + difference_type(1); __i != __last; ++__i) { + if (__comp(*__i, *__j)) { + value_type __t(_VSTD::move(*__i)); + _RandomAccessIterator __k = __j; __j = __i; + do { + *__j = _VSTD::move(*__k); + __j = __k; + } while (__j != __first && __comp(__t, *--__k)); + *__j = _VSTD::move(__t); + if (++__count == __limit) + return ++__i == __last; + } + __j = __i; } return true; } @@ -283,14 +279,16 @@ swap(*__first, *__last); return; case 3: - _VSTD::__sort3<_Compare>(__first, __first+1, --__last, __comp); - return; + _VSTD::__sort3<_Compare>(__first, __first + difference_type(1), --__last, __comp); + return; case 4: - _VSTD::__sort4<_Compare>(__first, __first+1, __first+2, --__last, __comp); - return; + _VSTD::__sort4<_Compare>(__first, __first + difference_type(1), __first + difference_type(2), --__last, + __comp); + return; case 5: - _VSTD::__sort5<_Compare>(__first, __first+1, __first+2, __first+3, --__last, __comp); - return; + _VSTD::__sort5<_Compare>(__first, __first + difference_type(1), __first + difference_type(2), + __first + difference_type(3), --__last, __comp); + return; } if (__len <= __limit) { @@ -421,20 +419,16 @@ if (__n_swaps == 0) { bool __fs = _VSTD::__insertion_sort_incomplete<_Compare>(__first, __i, __comp); - if (_VSTD::__insertion_sort_incomplete<_Compare>(__i+1, __last, __comp)) - { - if (__fs) - return; - __last = __i; + if (_VSTD::__insertion_sort_incomplete<_Compare>(__i + difference_type(1), __last, __comp)) { + if (__fs) + return; + __last = __i; + continue; + } else { + if (__fs) { + __first = ++__i; continue; - } - else - { - if (__fs) - { - __first = ++__i; - continue; - } + } } } // sort smaller range with recursive call and larger with tail recursion elimination @@ -446,9 +440,9 @@ } else { - _VSTD::__sort<_Compare>(__i+1, __last, __comp); - // _VSTD::__sort<_Compare>(__first, __i, __comp); - __last = __i; + _VSTD::__sort<_Compare>(__i + difference_type(1), __last, __comp); + // _VSTD::__sort<_Compare>(__first, __i, __comp); + __last = __i; } } } diff --git a/libcxx/test/std/algorithms/robust_re_difference_type.compile.pass.cpp b/libcxx/test/std/algorithms/robust_re_difference_type.compile.pass.cpp --- a/libcxx/test/std/algorithms/robust_re_difference_type.compile.pass.cpp +++ b/libcxx/test/std/algorithms/robust_re_difference_type.compile.pass.cpp @@ -77,6 +77,7 @@ auto mid = PickyIterator(a+5); auto last = PickyIterator(a+10); auto first2 = PickyIterator(b); + auto mid2 = PickyIterator(b + 5); auto last2 = PickyIterator(b+10); void *value = nullptr; int count = 1; @@ -84,7 +85,7 @@ (void)std::all_of(first, last, [](void*){ return true; }); (void)std::any_of(first, last, [](void*){ return true; }); (void)std::copy(first, last, first2); - // TODO FIXME (void)std::copy_n(first, count, first2); + (void)std::copy_n(first, count, first2); (void)std::copy_backward(first, last, last2); (void)std::count(first, last, value); (void)std::count_if(first, last, [](void*){ return true; }); @@ -132,7 +133,7 @@ (void)std::binary_search(first, last, value); (void)std::equal(first, last, first2); (void)std::equal_range(first, last, value); - // TODO FIXME (void)std::find_end(first, last, first2, mid2); + (void)std::find_end(first, last, first2, mid2); (void)std::includes(first, last, first2, last2); NOT_CONSTEVAL( (void)std::inplace_merge(first, mid, last); ) (void)std::is_heap(first, last); @@ -143,7 +144,7 @@ (void)std::lexicographical_compare(first, last, first2, last2); // TODO: lexicographical_compare_three_way (void)std::lower_bound(first, last, value); - // TODO FIXME (void)std::make_heap(first, last); + (void)std::make_heap(first, last); (void)std::max(value, value); (void)std::max({ value, value }); (void)std::max_element(first, last); @@ -157,19 +158,19 @@ (void)std::mismatch(first, last, first2); (void)std::next_permutation(first, last); (void)std::nth_element(first, mid, last); - // TODO FIXME (void)std::partial_sort(first, mid, last); - // TODO FIXME (void)std::partial_sort_copy(first, last, first2, mid2); - // TODO FIXME (void)std::pop_heap(first, last); + (void)std::partial_sort(first, mid, last); + (void)std::partial_sort_copy(first, last, first2, mid2); + (void)std::pop_heap(first, last); (void)std::prev_permutation(first, last); (void)std::push_heap(first, last); - // TODO FIXME (void)std::search(first, last, first2, mid2); - // TODO FIXME (void)std::search_n(first, last, count, value); + (void)std::search(first, last, first2, mid2); + (void)std::search_n(first, last, count, value); (void)std::set_difference(first, mid, mid, last, first2); (void)std::set_intersection(first, mid, mid, last, first2); (void)std::set_symmetric_difference(first, mid, mid, last, first2); (void)std::set_union(first, mid, mid, last, first2); - // TODO FIXME (void)std::sort(first, mid, last); - // TODO FIXME (void)std::sort_heap(first, last); + (void)std::sort(first, last); + (void)std::sort_heap(first, last); NOT_CONSTEVAL( (void)std::stable_sort(first, last); ) (void)std::unique(first, last); (void)std::unique_copy(first, last, first2); @@ -188,7 +189,7 @@ (void)std::binary_search(first, last, value, std::less()); (void)std::equal(first, last, first2, std::equal_to()); (void)std::equal_range(first, last, value, std::less()); - // TODO FIXME (void)std::find_end(first, last, first2, mid2, std::equal_to()); + (void)std::find_end(first, last, first2, mid2, std::equal_to()); (void)std::includes(first, last, first2, last2, std::less()); NOT_CONSTEVAL( (void)std::inplace_merge(first, mid, last, std::less()); ) (void)std::is_heap(first, last, std::less()); @@ -199,7 +200,7 @@ (void)std::lexicographical_compare(first, last, first2, last2, std::less()); // TODO: lexicographical_compare_three_way (void)std::lower_bound(first, last, value, std::less()); - // TODO FIXME (void)std::make_heap(first, last, std::less()); + (void)std::make_heap(first, last, std::less()); (void)std::max(value, value, std::less()); (void)std::max({ value, value }, std::less()); (void)std::max_element(first, last, std::less()); @@ -213,19 +214,19 @@ (void)std::mismatch(first, last, first2, std::equal_to()); (void)std::next_permutation(first, last, std::less()); (void)std::nth_element(first, mid, last, std::less()); - // TODO FIXME (void)std::partial_sort(first, mid, last, std::less()); - // TODO FIXME (void)std::partial_sort_copy(first, last, first2, mid2, std::less()); - // TODO FIXME (void)std::pop_heap(first, last, std::less()); + (void)std::partial_sort(first, mid, last, std::less()); + (void)std::partial_sort_copy(first, last, first2, mid2, std::less()); + (void)std::pop_heap(first, last, std::less()); (void)std::prev_permutation(first, last, std::less()); (void)std::push_heap(first, last, std::less()); - // TODO FIXME (void)std::search(first, last, first2, mid2, std::equal_to()); - // TODO FIXME (void)std::search_n(first, last, count, value, std::equal_to()); + (void)std::search(first, last, first2, mid2, std::equal_to()); + (void)std::search_n(first, last, count, value, std::equal_to()); (void)std::set_difference(first, mid, mid, last, first2, std::less()); (void)std::set_intersection(first, mid, mid, last, first2, std::less()); (void)std::set_symmetric_difference(first, mid, mid, last, first2, std::less()); (void)std::set_union(first, mid, mid, last, first2, std::less()); - // TODO FIXME (void)std::sort(first, mid, last, std::less()); - // TODO FIXME (void)std::sort_heap(first, last, std::less()); + (void)std::sort(first, last, std::less()); + (void)std::sort_heap(first, last, std::less()); NOT_CONSTEVAL( (void)std::stable_sort(first, last, std::less()); ) (void)std::unique(first, last, std::equal_to()); (void)std::unique_copy(first, last, first2, std::equal_to());