[libcxx-commits] [libcxx] 1821bc1 - [libc++] Fix the handling of `views::take` for `iota_view` (#75683)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Dec 18 12:41:18 PST 2023
Author: A. Jiang
Date: 2023-12-18T15:41:14-05:00
New Revision: 1821bc1e969bd2d0887fe115ae371506adc1a8be
URL: https://github.com/llvm/llvm-project/commit/1821bc1e969bd2d0887fe115ae371506adc1a8be
DIFF: https://github.com/llvm/llvm-project/commit/1821bc1e969bd2d0887fe115ae371506adc1a8be.diff
LOG: [libc++] Fix the handling of `views::take` for `iota_view` (#75683)
Currently, when libc++'s views::take specially handles an iota_view, the
addition is done after dereferencing the beginning iterator. However, in
[range.take.overview]/2.3, the addition is done before the dereferencing,
which means that the standard requires the returned iota_view to have
the same W and Bound type in such cases.
This patch fixes that, and also fixes a test that was testing the
incorrect behavior.
Fixes #75611
Added:
Modified:
libcxx/include/__ranges/take_view.h
libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index 4fd1d8b9ab8377..83ed5ca0ebd390 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -276,23 +276,31 @@ struct __fn {
}
// [range.take.overview]: the `iota_view` case.
+ // clang-format off
template <class _Range,
convertible_to<range_
diff erence_t<_Range>> _Np,
class _RawRange = remove_cvref_t<_Range>,
class _Dist = range_
diff erence_t<_Range>>
- requires(!__is_empty_view<_RawRange> && random_access_range<_RawRange> && sized_range<_RawRange> &&
- __is_iota_specialization<_RawRange>)
- [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto
- operator()(_Range&& __rng, _Np&& __n) const noexcept(noexcept(ranges::iota_view(
- *ranges::begin(__rng), *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))))
- -> decltype(ranges::iota_view(
- // Note: deliberately not forwarding `__rng` to guard against double moves.
- *ranges::begin(__rng),
- *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))) {
- return ranges::iota_view(*ranges::begin(__rng),
- *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)));
- }
- // clang-format off
+ requires (!__is_empty_view<_RawRange> &&
+ random_access_range<_RawRange> &&
+ sized_range<_RawRange> &&
+ __is_iota_specialization<_RawRange>)
+ [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+ constexpr auto operator()(_Range&& __rng, _Np&& __n) const
+ noexcept(noexcept(ranges::iota_view(
+ *ranges::begin(__rng),
+ *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
+ )))
+ -> decltype( ranges::iota_view(
+ // Note: deliberately not forwarding `__rng` to guard against double moves.
+ *ranges::begin(__rng),
+ *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
+ ))
+ { return ranges::iota_view(
+ *ranges::begin(__rng),
+ *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
+ ); }
+
#if _LIBCPP_STD_VER >= 23
// [range.take.overview]: the `repeat_view` "_RawRange models sized_range" case.
template <class _Range,
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
index 8ffac8d8fab153..bb5b5f5ff4909a 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
@@ -172,9 +172,8 @@ constexpr bool test() {
// `views::take(iota_view, n)` returns an `iota_view`.
{
auto iota = std::views::iota(1, 8);
- // The second template argument of the resulting `iota_view` is
diff erent because it has to be able to hold
- // the `range_
diff erence_t` of the input `iota_view`.
- using Result = std::ranges::iota_view<int, std::ranges::range_
diff erence_t<decltype(iota)>>;
+ // The second template argument of the resulting `iota_view` is same as the first.
+ using Result = std::ranges::iota_view<int, int>;
std::same_as<Result> decltype(auto) result = iota | std::views::take(3);
assert(result.size() == 3);
}
More information about the libcxx-commits
mailing list