[PATCH] libstdc++: Replace use of __mindist in ranges::uninitialized_xxx algos [PR101587]
Hewill Kang
hewillk@gmail.com
Fri Apr 4 09:39:31 GMT 2025
And iota<__int128>(0) | views::take(5) | views::transform([&v](auto i) ->
auto& { return v[i]; }) to create output range particularly for this case,
I think?
Tomasz Kaminski <tkaminsk@redhat.com>於 2025年4月4日 週五,17:31寫道:
>
>
> On Fri, Apr 4, 2025 at 11:10 AM Jonathan Wakely <jwakely@redhat.com>
> wrote:
>
>> In r15-8980-gf4b6acfc36fb1f I introduced a new function object for
>> finding the smaller of two distances. In bugzilla Hewill Kang pointed
>> out that we still need to explicitly convert the result back to the
>> right difference type, because the result might be an integer-like class
>> type that doesn't convert to an integral type explicitly.
>>
>> Rather than doing that conversion in the __mindist function object, I
>> think it's simpler to remove it again and just do a comparison and
>> assignment. We always want the result to have a specific type, so we can
>> just check if the value of the other type is smaller, and then convert
>> that to the other type if so.
>>
>> libstdc++-v3/ChangeLog:
>>
>> PR libstdc++/101587
>> * include/bits/ranges_uninitialized.h (__detail::__mindist):
>> Remove.
>> (ranges::uninitialized_copy, ranges::uninitialized_copy_n)
>> (ranges::uninitialized_move, ranges::uninitialized_move_n): Use
>> comparison and assignment instead of __mindist.
>> ---
>>
>> Tested x86_64-linux.
>>
> The revert makes sense, but this integer-like-classes are causing a lot of
> churm.
> I would like to see some tests for this scenario in algorithms tests.
> Using iota<__int128>(0, 5) is good way to produce integer-like difference
> type,
> that is sized. (iota<__int128>(0) | views::take(5)) creates not-sized one.
> With test LGTM.
>
>
>>
>> .../include/bits/ranges_uninitialized.h | 46 ++++++-------------
>> 1 file changed, 14 insertions(+), 32 deletions(-)
>>
>> diff --git a/libstdc++-v3/include/bits/ranges_uninitialized.h
>> b/libstdc++-v3/include/bits/ranges_uninitialized.h
>> index b5580073a6a..12a714b68aa 100644
>> --- a/libstdc++-v3/include/bits/ranges_uninitialized.h
>> +++ b/libstdc++-v3/include/bits/ranges_uninitialized.h
>> @@ -263,26 +263,6 @@ namespace ranges
>> inline constexpr __uninitialized_value_construct_n_fn
>> uninitialized_value_construct_n;
>>
>> - namespace __detail
>> - {
>> - // This is only intended for finding smaller iterator differences
>> below,
>> - // not as a general purpose replacement for std::min.
>> - struct __mindist_fn
>> - {
>> - template<typename _Dp1, typename _Dp2>
>> - constexpr common_type_t<_Dp1, _Dp2>
>> - operator()(_Dp1 __d1, _Dp2 __d2) const noexcept
>> - {
>> - // Every C++20 iterator I satisfies weakly_incrementable<I>
>> which
>> - // requires signed-integer-like<iter_difference_t<I>>.
>> - static_assert(std::__detail::__is_signed_integer_like<_Dp1>);
>> - static_assert(std::__detail::__is_signed_integer_like<_Dp2>);
>> - return std::min<common_type_t<_Dp1, _Dp2>>(__d1, __d2);
>> - }
>> - };
>> - inline constexpr __mindist_fn __mindist{};
>> - }
>> -
>> template<typename _Iter, typename _Out>
>> using uninitialized_copy_result = in_out_result<_Iter, _Out>;
>>
>> @@ -305,10 +285,10 @@ namespace ranges
>> && is_trivially_assignable_v<_OutType&,
>> iter_reference_t<_Iter>>)
>> {
>> - auto __d1 = __ilast - __ifirst;
>> - auto __d2 = __olast - __ofirst;
>> - return ranges::copy_n(std::move(__ifirst),
>> - __detail::__mindist(__d1, __d2),
>> __ofirst);
>> + auto __d = __ilast - __ifirst;
>> + if (auto __d2 = __olast - __ofirst; __d2 < __d)
>> + __d = static_cast<iter_difference_t<_Iter>>(__d2);
>> + return ranges::copy_n(std::move(__ifirst), __d, __ofirst);
>> }
>> else
>> {
>> @@ -356,9 +336,9 @@ namespace ranges
>> && is_trivially_assignable_v<_OutType&,
>> iter_reference_t<_Iter>>)
>> {
>> - auto __d = __olast - __ofirst;
>> - return ranges::copy_n(std::move(__ifirst),
>> - __detail::__mindist(__n, __d),
>> __ofirst);
>> + if (auto __d = __olast - __ofirst; __d < __n)
>> + __n = static_cast<iter_difference_t<_Iter>>(__d);
>> + return ranges::copy_n(std::move(__ifirst), __n, __ofirst);
>> }
>> else
>> {
>> @@ -397,11 +377,12 @@ namespace ranges
>> && is_trivially_assignable_v<_OutType&,
>>
>> iter_rvalue_reference_t<_Iter>>)
>> {
>> - auto __d1 = __ilast - __ifirst;
>> - auto __d2 = __olast - __ofirst;
>> + auto __d = __ilast - __ifirst;
>> + if (auto __d2 = __olast - __ofirst; __d2 < __d)
>> + __d = static_cast<iter_difference_t<_Iter>>(__d2);
>> auto [__in, __out]
>> =
>> ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
>> - __detail::__mindist(__d1, __d2), __ofirst);
>> + __d, __ofirst);
>> return {std::move(__in).base(), __out};
>> }
>> else
>> @@ -452,10 +433,11 @@ namespace ranges
>> && is_trivially_assignable_v<_OutType&,
>>
>> iter_rvalue_reference_t<_Iter>>)
>> {
>> - auto __d = __olast - __ofirst;
>> + if (auto __d = __olast - __ofirst; __d < __n)
>> + __n = static_cast<iter_difference_t<_Iter>>(__d);
>> auto [__in, __out]
>> =
>> ranges::copy_n(std::make_move_iterator(std::move(__ifirst)),
>> - __detail::__mindist(__n, __d), __ofirst);
>> + __n, __ofirst);
>> return {std::move(__in).base(), __out};
>> }
>> else
>> --
>> 2.49.0
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://gcc.gnu.org/pipermail/libstdc++/attachments/20250404/a9f3c2f0/attachment-0001.htm>
More information about the Libstdc++
mailing list