Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't throw arbitrary iterators at sized_sentinel_for #5027

Merged
merged 3 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
75 changes: 39 additions & 36 deletions stl/inc/algorithm
Original file line number Diff line number Diff line change
Expand Up @@ -1576,7 +1576,7 @@ namespace ranges {
auto _UFirst = _RANGES _Unwrap_iter<_Se1>(_STD move(_First));
auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It1>(_UFirst, _STD move(_Last));
_STD _Seek_wrapped(_First, _ULast);
const auto _Count = _STD _Idl_distance<_It1>(_UFirst, _ULast);
const auto _Count = _RANGES _Idl_distance<_It1>(_UFirst, _ULast);
auto _UOutput = _STD _Copy_backward_unchecked(
_STD move(_UFirst), _STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), -_Count));
_STD _Seek_wrapped(_Output, _STD move(_UOutput));
Expand Down Expand Up @@ -1714,7 +1714,7 @@ namespace ranges {
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
auto _UResult = _RANGES _Move_unchecked(
_STD move(_UFirst), _STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), _Count));

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

#if _HAS_CXX20
template <class _Diff1, class _Diff2>
_NODISCARD constexpr auto _Idl_dist_min([[maybe_unused]] const _Diff1 _Lhs, [[maybe_unused]] const _Diff2 _Rhs) {
// returns the minimum of two results from _Idl_distance calls
if constexpr (is_same_v<_Diff1, _Distance_unknown> || is_same_v<_Diff2, _Distance_unknown>) {
return _Distance_unknown{};
} else if constexpr (is_same_v<_Diff1, _Distance_unbounded>) {
return _Rhs;
} else if constexpr (is_same_v<_Diff2, _Distance_unbounded>) {
return _Lhs;
} else {
if (_Rhs < _Lhs) {
return static_cast<_Diff1>(_Rhs);
} else {
namespace ranges {
template <class _Diff1, class _Diff2>
_NODISCARD constexpr auto _Idl_dist_min([[maybe_unused]] const _Diff1 _Lhs, [[maybe_unused]] const _Diff2 _Rhs) {
// returns the minimum of two results from _Idl_distance calls
if constexpr (is_same_v<_Diff1, _Distance_unknown> || is_same_v<_Diff2, _Distance_unknown>) {
return _Distance_unknown{};
} else if constexpr (is_same_v<_Diff1, _Distance_unbounded>) {
return _Rhs;
} else if constexpr (is_same_v<_Diff2, _Distance_unbounded>) {
return _Lhs;
} else {
if (_Rhs < _Lhs) {
return static_cast<_Diff1>(_Rhs);
} else {
return _Lhs;
}
}
}
}

namespace ranges {
_EXPORT_STD template <class _In, class _Out>
using unary_transform_result = in_out_result<_In, _Out>;

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

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

auto _UFirst1 = _RANGES _Unwrap_iter<_Se1>(_STD move(_First1));
auto _ULast1 = _RANGES _Unwrap_sent<_It1>(_STD move(_Last1));
const auto _Count1 = _STD _Idl_distance<_It1>(_UFirst1, _ULast1);
const auto _Count1 = _RANGES _Idl_distance<_It1>(_UFirst1, _ULast1);
auto _UFirst2 = _RANGES _Unwrap_iter<_Se2>(_STD move(_First2));
auto _ULast2 = _RANGES _Unwrap_sent<_It2>(_STD move(_Last2));
const auto _Count2 = _STD _Idl_distance<_It2>(_UFirst2, _ULast2);
const auto _Count = _STD _Idl_dist_min(_Count1, _Count2);
const auto _Count2 = _RANGES _Idl_distance<_It2>(_UFirst2, _ULast2);
const auto _Count = _RANGES _Idl_dist_min(_Count1, _Count2);

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

Expand Down Expand Up @@ -4173,7 +4173,7 @@ namespace ranges {
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
auto _UResult = _Replace_copy_unchecked(_STD move(_UFirst), _STD move(_ULast),
_STD _Get_unwrapped_n(_STD move(_Output), _Count), _Oldval, _Newval, _STD _Pass_fn(_Proj));

Expand Down Expand Up @@ -4279,7 +4279,7 @@ namespace ranges {
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);

auto _UResult = _Replace_copy_if_unchecked(_STD move(_UFirst), _STD move(_ULast),
_STD _Get_unwrapped_n(_STD move(_Output), _Count), _STD _Pass_fn(_Pred), _Newval, _STD _Pass_fn(_Proj));
Expand Down Expand Up @@ -5199,7 +5199,7 @@ namespace ranges {
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
auto _ULast = _RANGES _Get_final_iterator_unwrapped<_It>(_UFirst, _STD move(_Last));
_STD _Seek_wrapped(_First, _ULast);
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
auto _UOutput = _Reverse_copy_common(
_STD move(_UFirst), _STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), _Count));
_STD _Seek_wrapped(_Output, _STD move(_UOutput));
Expand Down Expand Up @@ -5410,7 +5410,7 @@ namespace ranges {
_STD _Adl_verify_range(_Mid, _Last);
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
auto _UResult = _Rotate_copy_unchecked(_STD move(_UFirst), _RANGES _Unwrap_iter<_Se>(_STD move(_Mid)),
_STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), _Count));

Expand Down Expand Up @@ -7404,13 +7404,16 @@ template <class _Diff1, class _Diff2>
_NODISCARD constexpr auto _Idl_dist_add(_Diff1 _Lhs, _Diff2 _Rhs) {
(void) _Lhs;
(void) _Rhs;
if constexpr (is_same_v<_Diff1, _Distance_unbounded> || is_same_v<_Diff2, _Distance_unbounded>) {
return _Distance_unbounded{};
} else if constexpr (is_same_v<_Diff1, _Distance_unknown> || is_same_v<_Diff2, _Distance_unknown>) {
return _Distance_unknown{};
} else {
return _Lhs + _Rhs;
}
#if _HAS_CXX20
if constexpr (is_same_v<_Diff1, ranges::_Distance_unbounded> || is_same_v<_Diff2, ranges::_Distance_unbounded>) {
return ranges::_Distance_unbounded{};
} else
#endif // _HAS_CXX20
if constexpr (is_same_v<_Diff1, _Distance_unknown> || is_same_v<_Diff2, _Distance_unknown>) {
CaseyCarter marked this conversation as resolved.
Show resolved Hide resolved
return _Distance_unknown{};
} else {
return _Lhs + _Rhs;
}
}

_EXPORT_STD template <class _InIt1, class _InIt2, class _OutIt, class _Pr>
Expand Down Expand Up @@ -7502,10 +7505,10 @@ namespace ranges {
_STD _Adl_verify_range(_First2, _Last2);
auto _UFirst1 = _RANGES _Unwrap_iter<_Se1>(_STD move(_First1));
auto _ULast1 = _RANGES _Unwrap_sent<_It1>(_STD move(_Last1));
const auto _Count1 = _STD _Idl_distance<_It1>(_UFirst1, _ULast1);
const auto _Count1 = _RANGES _Idl_distance<_It1>(_UFirst1, _ULast1);
auto _UFirst2 = _RANGES _Unwrap_iter<_Se2>(_STD move(_First2));
auto _ULast2 = _RANGES _Unwrap_sent<_It2>(_STD move(_Last2));
const auto _Count2 = _STD _Idl_distance<_It2>(_UFirst2, _ULast2);
const auto _Count2 = _RANGES _Idl_distance<_It2>(_UFirst2, _ULast2);
const auto _Count = _STD _Idl_dist_add(_Count1, _Count2);
auto _UResult = _Merge_unchecked(_STD move(_UFirst1), _STD move(_ULast1), _STD move(_UFirst2),
_STD move(_ULast2), _STD _Get_unwrapped_n(_STD move(_Output), _Count), _STD _Pass_fn(_Pred),
Expand Down
84 changes: 42 additions & 42 deletions stl/inc/xutility
Original file line number Diff line number Diff line change
Expand Up @@ -1402,12 +1402,6 @@ struct _Distance_unknown {
}
};

struct _Distance_unbounded {
_NODISCARD constexpr _Distance_unbounded operator-() const noexcept {
return {};
}
};

template <class _Diff>
constexpr _Diff _Max_possible_v{static_cast<_Make_unsigned_like_t<_Diff>>(-1) >> 1};

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

#endif // _HAS_CXX17

#if _HAS_CXX20
_EXPORT_STD struct unreachable_sentinel_t;

template <class _Checked, class _Iter, class _Sent>
_NODISCARD constexpr auto _Idl_distance(const _Iter& _First, const _Sent& _Last) {
// Returns the distance between _First and _Last,
// an indicator that the distance is infinite, or
// an indicator that the distance cannot be determined in O(1).
_STL_INTERNAL_STATIC_ASSERT(same_as<_Unwrapped_t<_Checked>, _Iter>);

if constexpr (sized_sentinel_for<_Sent, _Iter>) {
return static_cast<iter_difference_t<_Checked>>(_Last - _First);
} else if constexpr (same_as<_Sent, unreachable_sentinel_t>) {
return _Distance_unbounded{};
} else {
return _Distance_unknown{};
}
}
#else // ^^^ _HAS_CXX20 / !_HAS_CXX20 vvv
template <class _Checked, class _Iter>
_NODISCARD constexpr auto _Idl_distance(const _Iter& _First, const _Iter& _Last) {
// Returns the distance between _First and _Last or
// an indicator that the distance cannot be determined in O(1).
_STL_INTERNAL_STATIC_ASSERT(is_same_v<_Unwrapped_t<_Checked>, _Iter>);
if constexpr (_Is_cpp17_random_iter_v<_Iter>) {
if constexpr (_Is_ranges_random_iter_v<_Iter>) {
return static_cast<_Iter_diff_t<_Checked>>(_Last - _First);
} else {
return _Distance_unknown{};
}
}
#endif // ^^^ !_HAS_CXX20 ^^^

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

_EXPORT_STD inline constexpr _Distance_fn distance;

template <range _Rng>
_NODISCARD constexpr auto _Idl_distance(_Rng& _Range) {
// Returns the length of _Range if it is finite and can be determined in O(1), or
// an indicator that the length is infinite, or
// an indicator that the length cannot be determined in O(1).
if constexpr (sized_range<_Rng>) {
return _RANGES distance(_Range);
} else if constexpr (same_as<sentinel_t<_Rng>, unreachable_sentinel_t>) {
return _Distance_unbounded{};
} else {
return _Distance_unknown{};
}
}

class _Ssize_fn {
public:
template <class _Rng>
Expand Down Expand Up @@ -4567,6 +4529,44 @@ _EXPORT_STD struct unreachable_sentinel_t {
};

_EXPORT_STD inline constexpr unreachable_sentinel_t unreachable_sentinel{};

namespace ranges {
struct _Distance_unbounded {
_NODISCARD constexpr _Distance_unbounded operator-() const noexcept {
return {};
}
};

template <class _Checked, class _Iter, class _Sent>
_NODISCARD constexpr auto _Idl_distance(const _Iter& _First, const _Sent& _Last) {
// Returns the distance between _First and _Last,
// an indicator that the distance is infinite, or
// an indicator that the distance cannot be determined in O(1).
_STL_INTERNAL_STATIC_ASSERT(same_as<_Unwrapped_t<_Checked>, _Iter>);

if constexpr (sized_sentinel_for<_Sent, _Iter>) {
return static_cast<iter_difference_t<_Checked>>(_Last - _First);
} else if constexpr (same_as<_Sent, unreachable_sentinel_t>) {
return _Distance_unbounded{};
} else {
return _Distance_unknown{};
}
}

template <range _Rng>
_NODISCARD constexpr auto _Idl_distance(_Rng& _Range) {
// Returns the length of _Range if it is finite and can be determined in O(1), or
// an indicator that the length is infinite, or
// an indicator that the length cannot be determined in O(1).
if constexpr (sized_range<_Rng>) {
return _RANGES distance(_Range);
} else if constexpr (same_as<sentinel_t<_Rng>, unreachable_sentinel_t>) {
return _Distance_unbounded{};
} else {
return _Distance_unknown{};
}
}
} // namespace ranges
#endif // _HAS_CXX20

// _Iterator_is_contiguous<_Iter> reports whether an iterator is known to be contiguous.
Expand Down Expand Up @@ -4961,7 +4961,7 @@ namespace ranges {
_STD _Adl_verify_range(_First, _Last);
auto _UFirst = _RANGES _Unwrap_iter<_Se>(_STD move(_First));
auto _ULast = _RANGES _Unwrap_sent<_It>(_STD move(_Last));
const auto _Count = _STD _Idl_distance<_It>(_UFirst, _ULast);
const auto _Count = _RANGES _Idl_distance<_It>(_UFirst, _ULast);
auto _UResult = _RANGES _Copy_unchecked(
_STD move(_UFirst), _STD move(_ULast), _STD _Get_unwrapped_n(_STD move(_Output), _Count));
_STD _Seek_wrapped(_First, _STD move(_UResult.in));
Expand Down
4 changes: 4 additions & 0 deletions tests/libcxx/expected_results.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ std/time/time.syn/formatter.year_month_weekday.pass.cpp:1 FAIL
std/time/time.syn/formatter.zoned_time.pass.cpp:0 FAIL
std/time/time.syn/formatter.zoned_time.pass.cpp:1 FAIL

# LLVM-74756: [libc++][test] overload_compare_iterator doesn't support its claimed iterator_category
std/utilities/memory/specialized.algorithms/uninitialized.copy/uninitialized_copy.pass.cpp FAIL
std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp FAIL

# LLVM-90196: [libc++][format] Formatting range with m range-type is incorrect
std/utilities/format/format.range/format.range.formatter/format.functions.format.pass.cpp FAIL
std/utilities/format/format.range/format.range.formatter/format.functions.vformat.pass.cpp FAIL
Expand Down