Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions stl/inc/__msvc_ranges_tuple_formatter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1086,13 +1086,15 @@ struct _Range_default_formatter<_Kind, _Rng, _CharT> {
template <class _FormatContext>
_FormatContext::iterator format(_Range_type& _Rx, _FormatContext& _Ctx) const {
if constexpr (_RANGES contiguous_range<_Range_type>) {
const auto _Size = _STD _To_unsigned_like(_RANGES distance(_Rx));
const auto _Dist = _RANGES distance(_Rx);
const auto _Size = _STD _To_unsigned_like(_Dist);

if (!_STD in_range<size_t>(_Size)) {
_Throw_format_error("Formatted range is too long.");
}

const basic_string_view<_CharT> _Str(_STD to_address(_RANGES begin(_Rx)), static_cast<size_t>(_Size));
const auto _First = _RANGES begin(_Rx);
const basic_string_view<_CharT> _Str(_STD to_address(_First), _STD to_address(_First + _Dist));
return _Underlying.format(_Str, _Ctx);
} else {
return _Underlying.format(basic_string<_CharT>{from_range, _Rx}, _Ctx);
Expand Down
77 changes: 48 additions & 29 deletions stl/inc/algorithm

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions stl/inc/format
Original file line number Diff line number Diff line change
Expand Up @@ -3367,9 +3367,10 @@ void _Range_formatter_format_as_sequence(const formatter<_Ty, _CharT>& _Underlyi
template <class _CharT, _RANGES input_range _Range, class _FormatContext>
void _Range_formatter_format_as_string(_Range&& _Rng, _FormatContext& _Ctx, const bool _Debug) {
if constexpr (_RANGES contiguous_range<_Range>) {
const auto _Size = _STD _To_unsigned_like(_RANGES distance(_Rng));
const auto _Dist = _RANGES distance(_Rng);

#ifdef _DEBUG
const auto _Size = _STD _To_unsigned_like(_Dist);
if constexpr (sizeof(_Size) > sizeof(size_t)) {
_STL_VERIFY(_Size <= size_t{PTRDIFF_MAX}, "contiguous range has impossible size.");
}
Expand All @@ -3380,7 +3381,8 @@ void _Range_formatter_format_as_string(_Range&& _Rng, _FormatContext& _Ctx, cons
_String_view_formatter.set_debug_format();
}

const basic_string_view<_CharT> _Str(_STD to_address(_RANGES begin(_Rng)), static_cast<size_t>(_Size));
const auto _First = _RANGES begin(_Rng);
const basic_string_view<_CharT> _Str(_STD to_address(_First), _STD to_address(_First + _Dist));
_String_view_formatter.format(_Str, _Ctx);
} else {
using _String = basic_string<_CharT>;
Expand Down
1 change: 1 addition & 0 deletions stl/inc/functional
Original file line number Diff line number Diff line change
Expand Up @@ -2527,6 +2527,7 @@ _CONSTEXPR20 pair<_FwdItHaystack, _FwdItHaystack> _Search_pair_unchecked(
if constexpr (_Vector_alg_in_search_is_safe<_FwdItHaystack, _FwdItPat, _Pred_eq>) {
if (!_STD _Is_constant_evaluated()) {
const auto _Ptr1 = _STD _To_address(_First1);
(void) _STD _To_address(_Last2);

const auto _Ptr_res1 = _STD _Search_vectorized(
_Ptr1, _STD _To_address(_Last1), _STD _To_address(_First2), static_cast<size_t>(_Count2));
Expand Down
14 changes: 10 additions & 4 deletions stl/inc/memory
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,14 @@ namespace ranges {
return _RANGES _Copy_memcpy_common(_IFirst, _RANGES next(_IFirst, _STD move(_ILast)), _OFirst,
_RANGES next(_OFirst, _STD move(_OLast)));
} else if constexpr (_Is_sized1) {
return _RANGES _Copy_memcpy_distance(
_IFirst, _OFirst, _IFirst, _RANGES next(_IFirst, _STD move(_ILast)));
const auto _Dist = _ILast - _IFirst;
_STD _Contiguous_iter_verify(_OFirst, static_cast<iter_difference_t<_Out>>(_Dist));
return _RANGES _Copy_memcpy_distance(_IFirst, _OFirst, _IFirst, _IFirst + _Dist);
} else {
_STL_INTERNAL_STATIC_ASSERT(_Is_sized2);
return _RANGES _Copy_memcpy_distance(
_IFirst, _OFirst, _OFirst, _RANGES next(_OFirst, _STD move(_OLast)));
const auto _Dist = _OLast - _OFirst;
_STD _Contiguous_iter_verify(_IFirst, static_cast<iter_difference_t<_It>>(_Dist));
return _RANGES _Copy_memcpy_distance(_IFirst, _OFirst, _OFirst, _OFirst + _Dist);
}
} else {
if constexpr (_Can_memcpy) {
Expand Down Expand Up @@ -200,6 +202,8 @@ namespace ranges {
_IFirst = _STD move(_UResult.in);
_OFirst = _STD move(_UResult.out);
} else {
_STD _Contiguous_iter_verify(_IFirst, _Count);
_STD _Contiguous_iter_verify(_OFirst, static_cast<iter_difference_t<_Out>>(_Count));
auto _UResult = _RANGES _Copy_memcpy_count(_IFirst, _OFirst, static_cast<size_t>(_Count));
_IFirst = _STD move(_UResult.in);
_OFirst = _STD move(_UResult.out);
Expand Down Expand Up @@ -363,6 +367,8 @@ namespace ranges {
_IFirst = _STD move(_UResult.in);
_OFirst = _STD move(_UResult.out);
} else {
_STD _Contiguous_iter_verify(_IFirst, _Count);
_STD _Contiguous_iter_verify(_OFirst, static_cast<iter_difference_t<_Out>>(_Count));
auto _UResult = _RANGES _Copy_memcpy_count(_IFirst, _OFirst, static_cast<size_t>(_Count));
_IFirst = _STD move(_UResult.in);
_OFirst = _STD move(_UResult.out);
Expand Down
20 changes: 13 additions & 7 deletions stl/inc/numeric
Original file line number Diff line number Diff line change
Expand Up @@ -489,21 +489,25 @@ _CONSTEXPR20 _OutIt adjacent_difference(const _InIt _First, const _InIt _Last, _
if (!_STD is_constant_evaluated())
#endif
{
const auto _Dest_dist = static_cast<_Iter_diff_t<decltype(_UDest)>>(_ULast - _UFirst);
_STD _Contiguous_iter_verify(_UDest, _Dest_dist);

// Go with pointers and without loop-carried dependency to enable vectorization
const auto _First_ptr = _STD _To_address(_UFirst);
const auto _Last_ptr = _STD _To_address(_ULast);
const auto _Dest_ptr = _STD _To_address(_UDest);
const auto _Count = _Last_ptr - _First_ptr;

// Need to perform aliasing analysis.
// The vectorizer is generally able to do that on its own, and would guard the vectorized code with
// that, but when we eliminate the loop-carried dependency we change the semantics of the unvectorized
// code too. So we need to perform this check manually, and after that we can tell the compiler that
// there's no aliasing, to avoid it checking for that again.
if (reinterpret_cast<uintptr_t>(_Dest_ptr + _Count) <= reinterpret_cast<uintptr_t>(_First_ptr)
if (reinterpret_cast<uintptr_t>(_Dest_ptr + static_cast<ptrdiff_t>(_Dest_dist))
<= reinterpret_cast<uintptr_t>(_First_ptr)
|| reinterpret_cast<uintptr_t>(_Last_ptr) <= reinterpret_cast<uintptr_t>(_Dest_ptr)) {
_STD _Adjacent_difference_no_overlap(_Dest_ptr, _First_ptr, _Count, _STD _Pass_fn(_Func));
_STD _Seek_wrapped(_Dest, _UDest + _Count);
_STD _Adjacent_difference_no_overlap(
_Dest_ptr, _First_ptr, static_cast<ptrdiff_t>(_Dest_dist), _STD _Pass_fn(_Func));
_STD _Seek_wrapped(_Dest, _UDest + _Dest_dist);
return _Dest;
}
}
Expand Down Expand Up @@ -556,7 +560,8 @@ _CONSTEXPR20 void iota(_FwdIt _First, _FwdIt _Last, _Ty _Val) {

if constexpr (_Iterator_is_contiguous<decltype(_UFirst)> && is_integral_v<_Ty> && sizeof(_Ty) >= 4) {
// TRANSITION, DevCom-10593477: help the compiler vectorize
const auto _Ptr = _To_address(_UFirst);
const auto _Ptr = _To_address(_UFirst);
(void) _STD _To_address(_ULast);
const auto _Size = static_cast<size_t>(_ULast - _UFirst);

if (_STD _In_range<_Ty>(_Size)) {
Expand Down Expand Up @@ -611,7 +616,8 @@ namespace ranges {
&& sizeof(_Ty) >= 4) {
// TRANSITION, DevCom-10593477: help the compiler vectorize
const auto _Ptr = _To_address(_First);
const auto _Size = static_cast<size_t>(_Last - _First);
const auto _Dist = _STD _Contiguous_iter_distance(_First, _Last);
const auto _Size = static_cast<size_t>(_Dist);

if (_STD _In_range<_Ty>(_Size)) {
const auto _Size_typed = static_cast<_Ty>(_Size);
Expand All @@ -621,7 +627,7 @@ namespace ranges {
}

_Val += _Size_typed;
return _First + _Size;
return _First + _Dist;
}
}

Expand Down
18 changes: 11 additions & 7 deletions stl/inc/xmemory
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,7 @@ namespace ranges {

template <class _InIt, class _OutIt>
in_out_result<_InIt, _OutIt> _Copy_memcpy_count(_InIt _IFirst, _OutIt _OFirst, const size_t _Count) noexcept {
// (pre-verified contiguous iterator)
const auto _IFirstPtr = _STD _To_address(_IFirst);
const auto _OFirstPtr = _STD _To_address(_OFirst);
const auto _IFirst_ch = const_cast<char*>(reinterpret_cast<const volatile char*>(_IFirstPtr));
Expand All @@ -1743,6 +1744,7 @@ namespace ranges {
template <class _InIt, class _OutIt, class _DistIt>
in_out_result<_InIt, _OutIt> _Copy_memcpy_distance(
_InIt _IFirst, _OutIt _OFirst, const _DistIt _DFirst, const _DistIt _DLast) noexcept {
// (pre-verified contiguous iterator)
// equivalent to _Copy_memcpy_count(_IFirst, _OFirst, _DLast - _DFirst) but computes distance more efficiently
const auto _IFirstPtr = _STD _To_address(_IFirst);
const auto _OFirstPtr = _STD _To_address(_OFirst);
Expand All @@ -1757,13 +1759,13 @@ namespace ranges {
if constexpr (is_pointer_v<_InIt>) {
_IFirst = reinterpret_cast<_InIt>(_IFirst_ch + _Count_bytes);
} else {
_IFirst += _Count_bytes / sizeof(iter_value_t<_InIt>);
_IFirst += static_cast<iter_difference_t<_InIt>>(_Count_bytes / sizeof(iter_value_t<_InIt>));
}

if constexpr (is_pointer_v<_OutIt>) {
_OFirst = reinterpret_cast<_OutIt>(_OFirst_ch + _Count_bytes);
} else {
_OFirst += _Count_bytes / sizeof(iter_value_t<_OutIt>);
_OFirst += static_cast<iter_difference_t<_OutIt>>(_Count_bytes / sizeof(iter_value_t<_OutIt>));
}
return {_STD move(_IFirst), _STD move(_OFirst)};
}
Expand Down Expand Up @@ -1813,12 +1815,14 @@ namespace ranges {
return _RANGES _Copy_memcpy_common(_IFirst, _RANGES next(_IFirst, _STD move(_ILast)), _OFirst,
_RANGES next(_OFirst, _STD move(_OLast)));
} else if constexpr (_Is_sized1) {
return _RANGES _Copy_memcpy_distance(
_IFirst, _OFirst, _IFirst, _RANGES next(_IFirst, _STD move(_ILast)));
const auto _Dist = _ILast - _IFirst;
_STD _Contiguous_iter_verify(_OFirst, static_cast<iter_difference_t<_Out>>(_Dist));
return _RANGES _Copy_memcpy_distance(_IFirst, _OFirst, _IFirst, _IFirst + _Dist);
} else {
_STL_INTERNAL_STATIC_ASSERT(_Is_sized2);
return _RANGES _Copy_memcpy_distance(
_IFirst, _OFirst, _OFirst, _RANGES next(_OFirst, _STD move(_OLast)));
const auto _Dist = _OLast - _OFirst;
_STD _Contiguous_iter_verify(_IFirst, static_cast<iter_difference_t<_It>>(_Dist));
return _RANGES _Copy_memcpy_distance(_IFirst, _OFirst, _OFirst, _OFirst + _Dist);
}
} else {
if constexpr (_Can_memcpy) {
Expand Down Expand Up @@ -1906,7 +1910,7 @@ _CONSTEXPR20 _Alloc_ptr_t<_Alloc> _Uninitialized_copy(
_STD _Copy_memmove(_STD _To_address(_UFirst), _STD _To_address(_ULast), _STD _Unfancy(_Dest));
_Dest += _ULast - _UFirst;
} else {
const auto _Count = static_cast<size_t>(_ULast - _UFirst);
const auto _Count = static_cast<size_t>(_STD _Contiguous_iter_distance(_UFirst, _ULast));
_STD _Copy_memmove_n(_STD _To_address(_UFirst), _Count, _STD _Unfancy(_Dest));
_Dest += _Count;
}
Expand Down
Loading
Loading