diff options
author | A. Jiang <de34@live.cn> | 2024-10-16 21:34:31 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-10-16 09:34:31 -0400 |
commit | cbe03646c620d08da69eac241450f32f4025c635 (patch) | |
tree | 6bcb442e8735ed77d89c2d7825a24faa6f885054 | |
parent | e839d2a60ac3149f09b3cda0816cf5074075733c (diff) | |
download | llvm-cbe03646c620d08da69eac241450f32f4025c635.zip llvm-cbe03646c620d08da69eac241450f32f4025c635.tar.gz llvm-cbe03646c620d08da69eac241450f32f4025c635.tar.bz2 |
[libc++][ranges] LWG3692: `zip_view::iterator`'s `operator<=>` is overconstrained and changes of `zip_view` in P2165R4 (#112077)
The changes are nearly pure simplifications, so I think it's OK to do
them together in the same PR.
Actual test coverages were already added in commit ad41d1e26b12
(https://reviews.llvm.org/D141216). Thanks to Casey Carter!
Fixes #104975
Towards #105200
9 files changed, 13 insertions, 102 deletions
diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv index 63e4176..cfa7212 100644 --- a/libcxx/docs/Status/Cxx23Issues.csv +++ b/libcxx/docs/Status/Cxx23Issues.csv @@ -168,7 +168,7 @@ "`LWG3672 <https://wg21.link/LWG3672>`__","``common_iterator::operator->()`` should return by value","2022-07 (Virtual)","|Complete|","19.0","" "`LWG3683 <https://wg21.link/LWG3683>`__","``operator==`` for ``polymorphic_allocator`` cannot deduce template argument in common cases","2022-07 (Virtual)","|Complete|","20.0","" "`LWG3687 <https://wg21.link/LWG3687>`__","``expected<cv void, E>`` move constructor should move","2022-07 (Virtual)","|Complete|","16.0","" -"`LWG3692 <https://wg21.link/LWG3692>`__","``zip_view::iterator``'s ``operator<=>`` is overconstrained","2022-07 (Virtual)","","","" +"`LWG3692 <https://wg21.link/LWG3692>`__","``zip_view::iterator``'s ``operator<=>`` is overconstrained","2022-07 (Virtual)","|Complete|","20.0","" "`LWG3701 <https://wg21.link/LWG3701>`__","Make ``formatter<remove_cvref_t<const charT[N]>, charT>`` requirement explicit","2022-07 (Virtual)","|Complete|","15.0","" "`LWG3702 <https://wg21.link/LWG3702>`__","Should ``zip_transform_view::iterator`` remove ``operator<``","2022-07 (Virtual)","","","" "`LWG3703 <https://wg21.link/LWG3703>`__","Missing requirements for ``expected<T, E>`` requires ``is_void<T>``","2022-07 (Virtual)","|Complete|","16.0","" diff --git a/libcxx/docs/Status/Cxx23Papers.csv b/libcxx/docs/Status/Cxx23Papers.csv index da7b588..c64f1c4 100644 --- a/libcxx/docs/Status/Cxx23Papers.csv +++ b/libcxx/docs/Status/Cxx23Papers.csv @@ -60,7 +60,7 @@ "`P1642R11 <https://wg21.link/P1642R11>`__","Freestanding ``[utilities]``, ``[ranges]``, and ``[iterators]``","2022-07 (Virtual)","","","" "`P1899R3 <https://wg21.link/P1899R3>`__","``stride_view``","2022-07 (Virtual)","","","" "`P2093R14 <https://wg21.link/P2093R14>`__","Formatted output","2022-07 (Virtual)","|Complete|","18.0","" -"`P2165R4 <https://wg21.link/P2165R4>`__","Compatibility between ``tuple``, ``pair`` and ``tuple-like`` objects","2022-07 (Virtual)","","","" +"`P2165R4 <https://wg21.link/P2165R4>`__","Compatibility between ``tuple``, ``pair`` and ``tuple-like`` objects","2022-07 (Virtual)","|Partial|","","Only the part for ``zip_view`` is implemented." "`P2278R4 <https://wg21.link/P2278R4>`__","``cbegin`` should always return a constant iterator","2022-07 (Virtual)","","","" "`P2286R8 <https://wg21.link/P2286R8>`__","Formatting Ranges","2022-07 (Virtual)","|Complete|","16.0","" "`P2291R3 <https://wg21.link/P2291R3>`__","Add Constexpr Modifiers to Functions ``to_chars`` and ``from_chars`` for Integral Types in ``<charconv>`` Header","2022-07 (Virtual)","|Complete|","16.0","" diff --git a/libcxx/include/__ranges/zip_view.h b/libcxx/include/__ranges/zip_view.h index fe3c87a..835e23c 100644 --- a/libcxx/include/__ranges/zip_view.h +++ b/libcxx/include/__ranges/zip_view.h @@ -36,7 +36,6 @@ #include <__utility/forward.h> #include <__utility/integer_sequence.h> #include <__utility/move.h> -#include <__utility/pair.h> #include <tuple> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) @@ -58,22 +57,11 @@ concept __zip_is_common = (!(bidirectional_range<_Ranges> && ...) && (common_range<_Ranges> && ...)) || ((random_access_range<_Ranges> && ...) && (sized_range<_Ranges> && ...)); -template <typename _Tp, typename _Up> -auto __tuple_or_pair_test() -> pair<_Tp, _Up>; - -template <typename... _Types> - requires(sizeof...(_Types) != 2) -auto __tuple_or_pair_test() -> tuple<_Types...>; - -template <class... _Types> -using __tuple_or_pair = decltype(__tuple_or_pair_test<_Types...>()); - template <class _Fun, class _Tuple> _LIBCPP_HIDE_FROM_ABI constexpr auto __tuple_transform(_Fun&& __f, _Tuple&& __tuple) { return std::apply( [&]<class... _Types>(_Types&&... __elements) { - return __tuple_or_pair<invoke_result_t<_Fun&, _Types>...>( - std::invoke(__f, std::forward<_Types>(__elements))...); + return tuple<invoke_result_t<_Fun&, _Types>...>(std::invoke(__f, std::forward<_Types>(__elements))...); }, std::forward<_Tuple>(__tuple)); } @@ -88,7 +76,7 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __tuple_for_each(_Fun&& __f, _Tuple&& __tup } template <class _Fun, class _Tuple1, class _Tuple2, size_t... _Indices> -_LIBCPP_HIDE_FROM_ABI constexpr __tuple_or_pair< +_LIBCPP_HIDE_FROM_ABI constexpr tuple< invoke_result_t<_Fun&, typename tuple_element<_Indices, remove_cvref_t<_Tuple1>>::type, typename tuple_element<_Indices, remove_cvref_t<_Tuple2>>::type>...> @@ -250,10 +238,9 @@ template <input_range... _Views> requires(view<_Views> && ...) && (sizeof...(_Views) > 0) template <bool _Const> class zip_view<_Views...>::__iterator : public __zip_view_iterator_category_base<_Const, _Views...> { - __tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current_; + tuple<iterator_t<__maybe_const<_Const, _Views>>...> __current_; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator( - __tuple_or_pair<iterator_t<__maybe_const<_Const, _Views>>...> __current) + _LIBCPP_HIDE_FROM_ABI constexpr explicit __iterator(tuple<iterator_t<__maybe_const<_Const, _Views>>...> __current) : __current_(std::move(__current)) {} template <bool> @@ -266,7 +253,7 @@ class zip_view<_Views...>::__iterator : public __zip_view_iterator_category_base public: using iterator_concept = decltype(__get_zip_view_iterator_tag<_Const, _Views...>()); - using value_type = __tuple_or_pair<range_value_t<__maybe_const<_Const, _Views>>...>; + using value_type = tuple<range_value_t<__maybe_const<_Const, _Views>>...>; using difference_type = common_type_t<range_difference_t<__maybe_const<_Const, _Views>>...>; _LIBCPP_HIDE_FROM_ABI __iterator() = default; @@ -340,33 +327,8 @@ public: } } - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<(const __iterator& __x, const __iterator& __y) - requires __zip_all_random_access<_Const, _Views...> - { - return __x.__current_ < __y.__current_; - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>(const __iterator& __x, const __iterator& __y) - requires __zip_all_random_access<_Const, _Views...> - { - return __y < __x; - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator<=(const __iterator& __x, const __iterator& __y) - requires __zip_all_random_access<_Const, _Views...> - { - return !(__y < __x); - } - - _LIBCPP_HIDE_FROM_ABI friend constexpr bool operator>=(const __iterator& __x, const __iterator& __y) - requires __zip_all_random_access<_Const, _Views...> - { - return !(__x < __y); - } - _LIBCPP_HIDE_FROM_ABI friend constexpr auto operator<=>(const __iterator& __x, const __iterator& __y) - requires __zip_all_random_access<_Const, _Views...> && - (three_way_comparable<iterator_t<__maybe_const<_Const, _Views>>> && ...) + requires __zip_all_random_access<_Const, _Views...> { return __x.__current_ <=> __y.__current_; } @@ -427,10 +389,9 @@ template <input_range... _Views> requires(view<_Views> && ...) && (sizeof...(_Views) > 0) template <bool _Const> class zip_view<_Views...>::__sentinel { - __tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end_; + tuple<sentinel_t<__maybe_const<_Const, _Views>>...> __end_; - _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel( - __tuple_or_pair<sentinel_t<__maybe_const<_Const, _Views>>...> __end) + _LIBCPP_HIDE_FROM_ABI constexpr explicit __sentinel(tuple<sentinel_t<__maybe_const<_Const, _Views>>...> __end) : __end_(__end) {} friend class zip_view<_Views...>; diff --git a/libcxx/test/std/ranges/range.adaptors/range.zip/cpo.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.zip/cpo.pass.cpp index ea5953c..bdfd58ff 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.zip/cpo.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.zip/cpo.pass.cpp @@ -63,11 +63,7 @@ constexpr bool test() { std::ranges::zip_view<std::ranges::zip_view<SizedRandomAccessView, SizedRandomAccessView>>> decltype(auto) v2 = std::views::zip(v); -#ifdef _LIBCPP_VERSION // libc++ doesn't implement P2165R4 yet - static_assert(std::is_same_v<std::ranges::range_reference_t<decltype(v2)>, std::tuple<std::pair<int&, int&>>>); -#else static_assert(std::is_same_v<std::ranges::range_reference_t<decltype(v2)>, std::tuple<std::tuple<int&, int&>>>); -#endif } return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.zip/ctor.default.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.zip/ctor.default.pass.cpp index f532896..fdfcc02 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.zip/ctor.default.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.zip/ctor.default.pass.cpp @@ -49,12 +49,8 @@ constexpr bool test() { using View = std::ranges::zip_view<DefaultConstructibleView, DefaultConstructibleView>; View v = View(); // the default constructor is not explicit assert(v.size() == 3); - auto it = v.begin(); -#ifdef _LIBCPP_VERSION // libc++ doesn't implement P2165R4 yet - using Value = std::pair<const int&, const int&>; -#else + auto it = v.begin(); using Value = std::tuple<const int&, const int&>; -#endif assert(*it++ == Value(buff[0], buff[0])); assert(*it++ == Value(buff[1], buff[1])); assert(*it == Value(buff[2], buff[2])); diff --git a/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/compare.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/compare.pass.cpp index ed1cb0c..8ab7346 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/compare.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/compare.pass.cpp @@ -10,17 +10,8 @@ // friend constexpr bool operator==(const iterator& x, const iterator& y) // requires (equality_comparable<iterator_t<maybe-const<Const, Views>>> && ...); -// friend constexpr bool operator<(const iterator& x, const iterator& y) -// requires all-random-access<Const, Views...>; -// friend constexpr bool operator>(const iterator& x, const iterator& y) -// requires all-random-access<Const, Views...>; -// friend constexpr bool operator<=(const iterator& x, const iterator& y) -// requires all-random-access<Const, Views...>; -// friend constexpr bool operator>=(const iterator& x, const iterator& y) -// requires all-random-access<Const, Views...>; // friend constexpr auto operator<=>(const iterator& x, const iterator& y) -// requires all-random-access<Const, Views...> && -// (three_way_comparable<iterator_t<maybe-const<Const, Views>>> && ...); +// requires all-random-access<Const, Views...>; #include <ranges> #include <compare> @@ -165,12 +156,7 @@ constexpr bool test() { using Subrange = std::ranges::subrange<It>; static_assert(!std::three_way_comparable<It>); using R = std::ranges::zip_view<Subrange, Subrange>; -#ifdef _LIBCPP_VERSION - // libc++ hasn't implemented LWG-3692 "zip_view::iterator's operator<=> is overconstrained" - static_assert(!std::three_way_comparable<std::ranges::iterator_t<R>>); -#else static_assert(std::three_way_comparable<std::ranges::iterator_t<R>>); -#endif int a[] = {1, 2, 3, 4}; int b[] = {5, 6, 7, 8, 9}; diff --git a/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/deref.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/deref.pass.cpp index 569d040..fb58aa2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/deref.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/deref.pass.cpp @@ -42,11 +42,7 @@ constexpr bool test() { auto [x, y] = *it; assert(&x == &(a[0])); assert(&y == &(b[0])); -#ifdef _LIBCPP_VERSION // libc++ doesn't implement P2165R4 yet - static_assert(std::is_same_v<decltype(*it), std::pair<int&, double&>>); -#else static_assert(std::is_same_v<decltype(*it), std::tuple<int&, double&>>); -#endif x = 5; y = 0.1; @@ -70,11 +66,7 @@ constexpr bool test() { auto it = v.begin(); assert(&(std::get<0>(*it)) == &(a[0])); assert(&(std::get<1>(*it)) == &(a[0])); -#ifdef _LIBCPP_VERSION // libc++ doesn't implement P2165R4 yet - static_assert(std::is_same_v<decltype(*it), std::pair<int&, int const&>>); -#else static_assert(std::is_same_v<decltype(*it), std::tuple<int&, int const&>>); -#endif } return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/member_types.compile.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/member_types.compile.pass.cpp index c19f6c2..2f2f0fc 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/member_types.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/member_types.compile.pass.cpp @@ -65,7 +65,7 @@ struct ConstVeryDifferentRange { void test() { int buffer[] = {1, 2, 3, 4}; { - // 2 views should have pair value_type + // 2 views should have 2-tuple value_type // random_access_iterator_tag std::ranges::zip_view v(buffer, buffer); using Iter = decltype(v.begin()); @@ -73,11 +73,7 @@ void test() { static_assert(std::is_same_v<Iter::iterator_concept, std::random_access_iterator_tag>); static_assert(std::is_same_v<Iter::iterator_category, std::input_iterator_tag>); static_assert(std::is_same_v<Iter::difference_type, std::ptrdiff_t>); -#ifdef _LIBCPP_VERSION // libc++ doesn't implement P2165R4 yet - static_assert(std::is_same_v<Iter::value_type, std::pair<int, int>>); -#else static_assert(std::is_same_v<Iter::value_type, std::tuple<int, int>>); -#endif static_assert(HasIterCategory<Iter>); } @@ -124,11 +120,7 @@ void test() { static_assert(std::is_same_v<Iter::iterator_concept, std::random_access_iterator_tag>); static_assert(std::is_same_v<Iter::iterator_category, std::input_iterator_tag>); static_assert(std::is_same_v<Iter::difference_type, std::ptrdiff_t>); -#ifdef _LIBCPP_VERSION // libc++ doesn't implement P2165R4 yet - static_assert(std::is_same_v<Iter::value_type, std::pair<int, std::pair<int, int>>>); -#else static_assert(std::is_same_v<Iter::value_type, std::tuple<int, std::tuple<int, int>>>); -#endif static_assert(HasIterCategory<Iter>); } @@ -169,11 +161,7 @@ void test() { // value_type of multiple views with different value_type std::ranges::zip_view v{foos, bars}; using Iter = decltype(v.begin()); -#ifdef _LIBCPP_VERSION // libc++ doesn't implement P2165R4 yet - static_assert(std::is_same_v<Iter::value_type, std::pair<Foo, Bar>>); -#else static_assert(std::is_same_v<Iter::value_type, std::tuple<Foo, Bar>>); -#endif } { diff --git a/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/subscript.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/subscript.pass.cpp index 1538d76..ba3abfa2 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/subscript.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.zip/iterator/subscript.pass.cpp @@ -27,11 +27,7 @@ constexpr bool test() { assert(it[2] == *(it + 2)); assert(it[4] == *(it + 4)); -#ifdef _LIBCPP_VERSION // libc++ doesn't implement P2165R4 yet - static_assert(std::is_same_v<decltype(it[2]), std::pair<int&, int>>); -#else static_assert(std::is_same_v<decltype(it[2]), std::tuple<int&, int>>); -#endif } { @@ -42,11 +38,7 @@ constexpr bool test() { assert(it[2] == *(it + 2)); assert(it[4] == *(it + 4)); -#ifdef _LIBCPP_VERSION // libc++ doesn't implement P2165R4 yet - static_assert(std::is_same_v<decltype(it[2]), std::pair<int&, int&>>); -#else static_assert(std::is_same_v<decltype(it[2]), std::tuple<int&, int&>>); -#endif } { |