Skip to content

Commit e0ad9c3

Browse files
authored
Don't throw arbitrary iterators at sized_sentinel_for (#5027)
1 parent f2a381b commit e0ad9c3

File tree

3 files changed

+85
-78
lines changed

3 files changed

+85
-78
lines changed

stl/inc/algorithm

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,7 +1576,7 @@ namespace ranges {
15761576
auto _UFirst = _RANGES _Unwrap_iter<_Se1>(_STD move(_First));
15771577
auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It1>(_UFirst, _STD move(_Last));
15781578
_STD _Seek_wrapped(_First, _ULast);
1579-
const auto _Count = _STD _Idl_distance<_It1>(_UFirst, _ULast);
1579+
const auto _Count = _RANGES _Idl_distance<_It1>(_UFirst, _ULast);
15801580
auto _UOutput = _STD _Copy_backward_unchecked(
15811581
_STD move(_UFirst), _STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), -_Count));
15821582
_STD _Seek_wrapped(_Output, _STD move(_UOutput));
@@ -1714,7 +1714,7 @@ namespace ranges {
17141714
_STD _Adl_verify_range(_First, _Last);
17151715
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
17161716
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
1717-
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
1717+
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
17181718
auto _UResult = _RANGES _Move_unchecked(
17191719
_STD move(_UFirst), _STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), _Count));
17201720

@@ -1770,7 +1770,7 @@ namespace ranges {
17701770
auto _UFirst = _RANGES _Unwrap_iter<_Se1>(_STD move(_First));
17711771
auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It1>(_UFirst, _STD move(_Last));
17721772
_STD _Seek_wrapped(_First, _ULast);
1773-
const auto _Count = _STD _Idl_distance<_It1>(_UFirst, _ULast);
1773+
const auto _Count = _RANGES _Idl_distance<_It1>(_UFirst, _ULast);
17741774
auto _UOutput = _RANGES _Move_backward_common(
17751775
_STD move(_UFirst), _STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), -_Count));
17761776
_STD _Seek_wrapped(_Output, _STD move(_UOutput));
@@ -3786,25 +3786,25 @@ _FwdIt3 transform(_ExPo&& _Exec, _FwdIt1 _First1, _FwdIt1 _Last1, _FwdIt2 _First
37863786
#endif // _HAS_CXX17
37873787

37883788
#if _HAS_CXX20
3789-
template <class _Diff1, class _Diff2>
3790-
_NODISCARD constexpr auto _Idl_dist_min([[maybe_unused]] const _Diff1 _Lhs, [[maybe_unused]] const _Diff2 _Rhs) {
3791-
// returns the minimum of two results from _Idl_distance calls
3792-
if constexpr (is_same_v<_Diff1, _Distance_unknown> || is_same_v<_Diff2, _Distance_unknown>) {
3793-
return _Distance_unknown{};
3794-
} else if constexpr (is_same_v<_Diff1, _Distance_unbounded>) {
3795-
return _Rhs;
3796-
} else if constexpr (is_same_v<_Diff2, _Distance_unbounded>) {
3797-
return _Lhs;
3798-
} else {
3799-
if (_Rhs < _Lhs) {
3800-
return static_cast<_Diff1>(_Rhs);
3801-
} else {
3789+
namespace ranges {
3790+
template <class _Diff1, class _Diff2>
3791+
_NODISCARD constexpr auto _Idl_dist_min([[maybe_unused]] const _Diff1 _Lhs, [[maybe_unused]] const _Diff2 _Rhs) {
3792+
// returns the minimum of two results from _Idl_distance calls
3793+
if constexpr (is_same_v<_Diff1, _Distance_unknown> || is_same_v<_Diff2, _Distance_unknown>) {
3794+
return _Distance_unknown{};
3795+
} else if constexpr (is_same_v<_Diff1, _Distance_unbounded>) {
3796+
return _Rhs;
3797+
} else if constexpr (is_same_v<_Diff2, _Distance_unbounded>) {
38023798
return _Lhs;
3799+
} else {
3800+
if (_Rhs < _Lhs) {
3801+
return static_cast<_Diff1>(_Rhs);
3802+
} else {
3803+
return _Lhs;
3804+
}
38033805
}
38043806
}
3805-
}
38063807

3807-
namespace ranges {
38083808
_EXPORT_STD template <class _In, class _Out>
38093809
using unary_transform_result = in_out_result<_In, _Out>;
38103810

@@ -3821,7 +3821,7 @@ namespace ranges {
38213821
_STD _Adl_verify_range(_First, _Last);
38223822
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
38233823
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
3824-
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
3824+
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
38253825

38263826
auto _UResult = _Transform_unary_unchecked(_STD move(_UFirst), _STD move(_ULast),
38273827
_STD _Get_unwrapped_n(_STD move(_Output), _Count), _STD _Pass_fn(_Func), _STD _Pass_fn(_Proj));
@@ -3858,11 +3858,11 @@ namespace ranges {
38583858

38593859
auto _UFirst1 = _RANGES _Unwrap_iter<_Se1>(_STD move(_First1));
38603860
auto _ULast1 = _RANGES _Unwrap_sent<_It1>(_STD move(_Last1));
3861-
const auto _Count1 = _STD _Idl_distance<_It1>(_UFirst1, _ULast1);
3861+
const auto _Count1 = _RANGES _Idl_distance<_It1>(_UFirst1, _ULast1);
38623862
auto _UFirst2 = _RANGES _Unwrap_iter<_Se2>(_STD move(_First2));
38633863
auto _ULast2 = _RANGES _Unwrap_sent<_It2>(_STD move(_Last2));
3864-
const auto _Count2 = _STD _Idl_distance<_It2>(_UFirst2, _ULast2);
3865-
const auto _Count = _STD _Idl_dist_min(_Count1, _Count2);
3864+
const auto _Count2 = _RANGES _Idl_distance<_It2>(_UFirst2, _ULast2);
3865+
const auto _Count = _RANGES _Idl_dist_min(_Count1, _Count2);
38663866

38673867
auto _UResult = _Transform_binary_unchecked(_STD move(_UFirst1), _STD move(_ULast1), _STD move(_UFirst2),
38683868
_STD move(_ULast2), _STD _Get_unwrapped_n(_STD move(_Output), _Count), _STD _Pass_fn(_Func),
@@ -3882,7 +3882,7 @@ namespace ranges {
38823882
_Out>
38833883
operator()(_Rng1&& _Range1, _Rng2&& _Range2, _Out _Output, _Fn _Func, _Pj1 _Proj1 = {},
38843884
_Pj2 _Proj2 = {}) _CONST_CALL_OPERATOR {
3885-
const auto _Count = _STD _Idl_dist_min(_RANGES _Idl_distance(_Range1), _RANGES _Idl_distance(_Range2));
3885+
const auto _Count = _RANGES _Idl_dist_min(_RANGES _Idl_distance(_Range1), _RANGES _Idl_distance(_Range2));
38863886
auto _First1 = _RANGES begin(_Range1);
38873887
auto _First2 = _RANGES begin(_Range2);
38883888

@@ -4173,7 +4173,7 @@ namespace ranges {
41734173
_STD _Adl_verify_range(_First, _Last);
41744174
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
41754175
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
4176-
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
4176+
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
41774177
auto _UResult = _Replace_copy_unchecked(_STD move(_UFirst), _STD move(_ULast),
41784178
_STD _Get_unwrapped_n(_STD move(_Output), _Count), _Oldval, _Newval, _STD _Pass_fn(_Proj));
41794179

@@ -4279,7 +4279,7 @@ namespace ranges {
42794279
_STD _Adl_verify_range(_First, _Last);
42804280
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
42814281
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
4282-
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
4282+
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
42834283

42844284
auto _UResult = _Replace_copy_if_unchecked(_STD move(_UFirst), _STD move(_ULast),
42854285
_STD _Get_unwrapped_n(_STD move(_Output), _Count), _STD _Pass_fn(_Pred), _Newval, _STD _Pass_fn(_Proj));
@@ -5199,7 +5199,7 @@ namespace ranges {
51995199
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
52005200
auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last));
52015201
_STD _Seek_wrapped(_First, _ULast);
5202-
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
5202+
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
52035203
auto _UOutput = _Reverse_copy_common(
52045204
_STD move(_UFirst), _STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), _Count));
52055205
_STD _Seek_wrapped(_Output, _STD move(_UOutput));
@@ -5410,7 +5410,7 @@ namespace ranges {
54105410
_STD _Adl_verify_range(_Mid, _Last);
54115411
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
54125412
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
5413-
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
5413+
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
54145414
auto _UResult = _Rotate_copy_unchecked(_STD move(_UFirst), _RANGES _Unwrap_iter<_Se>(_STD move(_Mid)),
54155415
_STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), _Count));
54165416

@@ -7404,13 +7404,16 @@ template <class _Diff1, class _Diff2>
74047404
_NODISCARD constexpr auto _Idl_dist_add(_Diff1 _Lhs, _Diff2 _Rhs) {
74057405
(void) _Lhs;
74067406
(void) _Rhs;
7407-
if constexpr (is_same_v<_Diff1, _Distance_unbounded> || is_same_v<_Diff2, _Distance_unbounded>) {
7408-
return _Distance_unbounded{};
7409-
} else if constexpr (is_same_v<_Diff1, _Distance_unknown> || is_same_v<_Diff2, _Distance_unknown>) {
7410-
return _Distance_unknown{};
7411-
} else {
7412-
return _Lhs + _Rhs;
7413-
}
7407+
#if _HAS_CXX20
7408+
if constexpr (is_same_v<_Diff1, ranges::_Distance_unbounded> || is_same_v<_Diff2, ranges::_Distance_unbounded>) {
7409+
return ranges::_Distance_unbounded{};
7410+
} else
7411+
#endif // _HAS_CXX20
7412+
if constexpr (is_same_v<_Diff1, _Distance_unknown> || is_same_v<_Diff2, _Distance_unknown>) {
7413+
return _Distance_unknown{};
7414+
} else {
7415+
return _Lhs + _Rhs;
7416+
}
74147417
}
74157418

74167419
_EXPORT_STD template <class _InIt1, class _InIt2, class _OutIt, class _Pr>
@@ -7502,10 +7505,10 @@ namespace ranges {
75027505
_STD _Adl_verify_range(_First2, _Last2);
75037506
auto _UFirst1 = _RANGES _Unwrap_iter<_Se1>(_STD move(_First1));
75047507
auto _ULast1 = _RANGES _Unwrap_sent<_It1>(_STD move(_Last1));
7505-
const auto _Count1 = _STD _Idl_distance<_It1>(_UFirst1, _ULast1);
7508+
const auto _Count1 = _RANGES _Idl_distance<_It1>(_UFirst1, _ULast1);
75067509
auto _UFirst2 = _RANGES _Unwrap_iter<_Se2>(_STD move(_First2));
75077510
auto _ULast2 = _RANGES _Unwrap_sent<_It2>(_STD move(_Last2));
7508-
const auto _Count2 = _STD _Idl_distance<_It2>(_UFirst2, _ULast2);
7511+
const auto _Count2 = _RANGES _Idl_distance<_It2>(_UFirst2, _ULast2);
75097512
const auto _Count = _STD _Idl_dist_add(_Count1, _Count2);
75107513
auto _UResult = _Merge_unchecked(_STD move(_UFirst1), _STD move(_ULast1), _STD move(_UFirst2),
75117514
_STD move(_ULast2), _STD _Get_unwrapped_n(_STD move(_Output), _Count), _STD _Pass_fn(_Pred),

stl/inc/xutility

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,12 +1402,6 @@ struct _Distance_unknown {
14021402
}
14031403
};
14041404

1405-
struct _Distance_unbounded {
1406-
_NODISCARD constexpr _Distance_unbounded operator-() const noexcept {
1407-
return {};
1408-
}
1409-
};
1410-
14111405
template <class _Diff>
14121406
constexpr _Diff _Max_possible_v{static_cast<_Make_unsigned_like_t<_Diff>>(-1) >> 1};
14131407

@@ -1532,35 +1526,17 @@ using _Enable_if_execution_policy_t = typename remove_reference_t<_ExPo>::_Stand
15321526

15331527
#endif // _HAS_CXX17
15341528

1535-
#if _HAS_CXX20
1536-
_EXPORT_STD struct unreachable_sentinel_t;
1537-
1538-
template <class _Checked, class _Iter, class _Sent>
1539-
_NODISCARD constexpr auto _Idl_distance(const _Iter& _First, const _Sent& _Last) {
1540-
// Returns the distance between _First and _Last,
1541-
// an indicator that the distance is infinite, or
1542-
// an indicator that the distance cannot be determined in O(1).
1543-
_STL_INTERNAL_STATIC_ASSERT(same_as<_Unwrapped_t<_Checked>, _Iter>);
1544-
1545-
if constexpr (sized_sentinel_for<_Sent, _Iter>) {
1546-
return static_cast<iter_difference_t<_Checked>>(_Last - _First);
1547-
} else if constexpr (same_as<_Sent, unreachable_sentinel_t>) {
1548-
return _Distance_unbounded{};
1549-
} else {
1550-
return _Distance_unknown{};
1551-
}
1552-
}
1553-
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
15541529
template <class _Checked, class _Iter>
15551530
_NODISCARD constexpr auto _Idl_distance(const _Iter& _First, const _Iter& _Last) {
1531+
// Returns the distance between _First and _Last or
1532+
// an indicator that the distance cannot be determined in O(1).
15561533
_STL_INTERNAL_STATIC_ASSERT(is_same_v<_Unwrapped_t<_Checked>, _Iter>);
1557-
if constexpr (_Is_cpp17_random_iter_v<_Iter>) {
1534+
if constexpr (_Is_ranges_random_iter_v<_Iter>) {
15581535
return static_cast<_Iter_diff_t<_Checked>>(_Last - _First);
15591536
} else {
15601537
return _Distance_unknown{};
15611538
}
15621539
}
1563-
#endif // ^^^ !_HAS_CXX20 ^^^
15641540

15651541
template <class _Elem, bool _Is_enum = is_enum_v<_Elem>>
15661542
struct _Unwrap_enum { // if _Elem is an enum, gets its underlying type; otherwise leaves _Elem unchanged
@@ -3582,20 +3558,6 @@ namespace ranges {
35823558

35833559
_EXPORT_STD inline constexpr _Distance_fn distance;
35843560

3585-
template <range _Rng>
3586-
_NODISCARD constexpr auto _Idl_distance(_Rng& _Range) {
3587-
// Returns the length of _Range if it is finite and can be determined in O(1), or
3588-
// an indicator that the length is infinite, or
3589-
// an indicator that the length cannot be determined in O(1).
3590-
if constexpr (sized_range<_Rng>) {
3591-
return _RANGES distance(_Range);
3592-
} else if constexpr (same_as<sentinel_t<_Rng>, unreachable_sentinel_t>) {
3593-
return _Distance_unbounded{};
3594-
} else {
3595-
return _Distance_unknown{};
3596-
}
3597-
}
3598-
35993561
class _Ssize_fn {
36003562
public:
36013563
template <class _Rng>
@@ -4567,6 +4529,44 @@ _EXPORT_STD struct unreachable_sentinel_t {
45674529
};
45684530

45694531
_EXPORT_STD inline constexpr unreachable_sentinel_t unreachable_sentinel{};
4532+
4533+
namespace ranges {
4534+
struct _Distance_unbounded {
4535+
_NODISCARD constexpr _Distance_unbounded operator-() const noexcept {
4536+
return {};
4537+
}
4538+
};
4539+
4540+
template <class _Checked, class _Iter, class _Sent>
4541+
_NODISCARD constexpr auto _Idl_distance(const _Iter& _First, const _Sent& _Last) {
4542+
// Returns the distance between _First and _Last,
4543+
// an indicator that the distance is infinite, or
4544+
// an indicator that the distance cannot be determined in O(1).
4545+
_STL_INTERNAL_STATIC_ASSERT(same_as<_Unwrapped_t<_Checked>, _Iter>);
4546+
4547+
if constexpr (sized_sentinel_for<_Sent, _Iter>) {
4548+
return static_cast<iter_difference_t<_Checked>>(_Last - _First);
4549+
} else if constexpr (same_as<_Sent, unreachable_sentinel_t>) {
4550+
return _Distance_unbounded{};
4551+
} else {
4552+
return _Distance_unknown{};
4553+
}
4554+
}
4555+
4556+
template <range _Rng>
4557+
_NODISCARD constexpr auto _Idl_distance(_Rng& _Range) {
4558+
// Returns the length of _Range if it is finite and can be determined in O(1), or
4559+
// an indicator that the length is infinite, or
4560+
// an indicator that the length cannot be determined in O(1).
4561+
if constexpr (sized_range<_Rng>) {
4562+
return _RANGES distance(_Range);
4563+
} else if constexpr (same_as<sentinel_t<_Rng>, unreachable_sentinel_t>) {
4564+
return _Distance_unbounded{};
4565+
} else {
4566+
return _Distance_unknown{};
4567+
}
4568+
}
4569+
} // namespace ranges
45704570
#endif // _HAS_CXX20
45714571

45724572
// _Iterator_is_contiguous<_Iter> reports whether an iterator is known to be contiguous.
@@ -4961,7 +4961,7 @@ namespace ranges {
49614961
_STD _Adl_verify_range(_First, _Last);
49624962
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
49634963
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
4964-
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
4964+
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
49654965
auto _UResult = _RANGES _Copy_unchecked(
49664966
_STD move(_UFirst), _STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), _Count));
49674967
_STD _Seek_wrapped(_First, _STD move(_UResult.in));

tests/libcxx/expected_results.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ std/time/time.syn/formatter.year_month_weekday.pass.cpp:1 FAIL
2424
std/time/time.syn/formatter.zoned_time.pass.cpp:0 FAIL
2525
std/time/time.syn/formatter.zoned_time.pass.cpp:1 FAIL
2626

27+
# LLVM-74756: [libc++][test] overload_compare_iterator doesn't support its claimed iterator_category
28+
std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp FAIL
29+
std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp FAIL
30+
2731
# LLVM-90196: [libc++][format] Formatting range with m range-type is incorrect
2832
std/utilities/format/format.range/format.range.formatter/format.functions.format.pass.cpp FAIL
2933
std/utilities/format/format.range/format.range.formatter/format.functions.vformat.pass.cpp FAIL

0 commit comments

Comments
 (0)