Skip to content
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
11f9feb
Implement P3349R1
NylteJ Aug 17, 2025
cb8802b
Moved comment in `yvals_core.h`
NylteJ Aug 18, 2025
c3e4dc0
Change test standard to C++20
NylteJ Aug 18, 2025
33f5b7b
Merge branch 'main' into P3349R1
NylteJ Oct 19, 2025
421726b
Merge branch 'main' into P3349R1
NylteJ Oct 24, 2025
45881ac
Resolve stealth conflict with #5590
NylteJ Oct 24, 2025
253558b
Merge branch 'main' into P3349R1
StephanTLavavej Nov 3, 2025
96d1498
Add newlines.
StephanTLavavej Nov 3, 2025
3555bbf
Simplify a wmemchr() call into step-by-step casts.
StephanTLavavej Nov 3, 2025
d93eb1d
nothrow => Nothrow
StephanTLavavej Nov 3, 2025
1c1126f
`enum range_type` => `enum class range_type`
StephanTLavavej Nov 3, 2025
cad143b
Include more headers.
StephanTLavavej Nov 3, 2025
b38e120
Assert one thing at a time.
StephanTLavavej Nov 3, 2025
cfa1d9c
Comment cleanups.
StephanTLavavej Nov 3, 2025
b5c8625
Raw string literals are cool string literals.
StephanTLavavej Nov 3, 2025
1e06f30
Drop default `false` for `safe_iter`.
StephanTLavavej Nov 3, 2025
d69296a
Drop unnecessary `operator==` overload.
StephanTLavavej Nov 3, 2025
4816074
Comment `operator->` being unconditionally `noexcept`.
StephanTLavavej Nov 3, 2025
67f1aee
Teach `operator+=` how to set the `Nothrow` bool.
StephanTLavavej Nov 3, 2025
2cf5a39
Drop `bad_range_2`, extract `last_ptr` to simplify.
StephanTLavavej Nov 3, 2025
d11fa88
`range_size` => `RangeSize`
StephanTLavavej Nov 3, 2025
06981ca
Add cross-tests with non-vectorization
NylteJ Nov 4, 2025
7f59667
Fix tests
NylteJ Nov 4, 2025
20a8377
Improve test coverage
NylteJ Nov 4, 2025
0308404
Avoid `search_n` forwarding to `find`
NylteJ Nov 4, 2025
b639c7f
Revert "Teach `operator+=` how to set the `Nothrow` bool."
NylteJ Nov 4, 2025
914014b
Revert "Drop `bad_range_2`, extract `last_ptr` to simplify."
NylteJ Nov 4, 2025
9c436be
Extract `last_ptr` to simplify
NylteJ Nov 4, 2025
e963301
Format
NylteJ Nov 4, 2025
b897b7f
No, not usual_matrix
NylteJ Nov 4, 2025
a851166
Explain the remove_copy/unique_copy limitation in more detail, citing…
StephanTLavavej Nov 4, 2025
47fab07
Move the increment/decrement comment to `operator+=` where it applies.
StephanTLavavej Nov 4, 2025
051ebcf
unwrap() can be noexcept.
StephanTLavavej Nov 4, 2025
5c95536
`safe_iter` consistently uses `pointer`.
StephanTLavavej Nov 4, 2025
cbcebf2
Add one more assertion for completeness.
StephanTLavavej Nov 4, 2025
2f2bb28
Unique numbers for unique purposes.
StephanTLavavej Nov 4, 2025
5e22a56
Use `array` instead of `initializer_list`.
StephanTLavavej Nov 4, 2025
2f163a7
Replace rng_last_ptr with valid_last_ptr.
StephanTLavavej Nov 4, 2025
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