[libcxx-commits] [libcxx] [libc++][ranges] LWG3564: `transform_view::iterator<true>::value_type` and `iterator_category` should use `const F&` (PR #91816)

Xiaoyang Liu via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 24 13:01:39 PDT 2024


https://github.com/xiaoyang-sde updated https://github.com/llvm/llvm-project/pull/91816

>From 4c316128dba33eb0be5cd3ba51e1c6872d03cbf8 Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Fri, 10 May 2024 17:44:11 -0400
Subject: [PATCH 1/4] [libc++][ranges] LWG3564:
 'transform_view::iterator<true>::value_type' and 'iterator_category' should
 use 'const F&'

---
 libcxx/docs/Status/Cxx23Issues.csv                |  2 +-
 libcxx/include/__ranges/transform_view.h          | 12 ++++++------
 .../range.transform/iterator/types.pass.cpp       | 15 +++++++++++++++
 .../ranges/range.adaptors/range.transform/types.h |  5 +++++
 4 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index 04f6e23375acd..fef60d289f86f 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -159,7 +159,7 @@
 "`3660 <https://wg21.link/LWG3660>`__","``iterator_traits<common_iterator>::pointer`` should conform to §[iterator.traits]","February 2022","|Complete|","14.0","|ranges|"
 "`3661 <https://wg21.link/LWG3661>`__","``constinit atomic<shared_ptr<T>> a(nullptr);`` should work","February 2022","",""
 "","","","","",""
-"`3564 <https://wg21.link/LWG3564>`__","``transform_view::iterator<true>::value_type`` and ``iterator_category`` should use ``const F&``","July 2022","","","|ranges|"
+"`3564 <https://wg21.link/LWG3564>`__","``transform_view::iterator<true>::value_type`` and ``iterator_category`` should use ``const F&``","July 2022","|Complete|","19.0","|ranges|"
 "`3617 <https://wg21.link/LWG3617>`__","``function``/``packaged_task`` deduction guides and deducing ``this``","July 2022","",""
 "`3656 <https://wg21.link/LWG3656>`__","Inconsistent bit operations returning a count","July 2022","|Complete|","15.0",""
 "`3659 <https://wg21.link/LWG3659>`__","Consider ``ATOMIC_FLAG_INIT`` undeprecation","July 2022","|Complete|","15.0"
diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index dc3aaa59ed8c3..af973076e04f8 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -153,15 +153,15 @@ struct __transform_view_iterator_concept<_View> {
   using type = forward_iterator_tag;
 };
 
-template <class, class>
+template <class, class, bool>
 struct __transform_view_iterator_category_base {};
 
-template <forward_range _View, class _Fn>
-struct __transform_view_iterator_category_base<_View, _Fn> {
+template <forward_range _View, class _Fn, bool _Const>
+struct __transform_view_iterator_category_base<_View, _Fn, _Const> {
   using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category;
 
   using iterator_category =
-      conditional_t< is_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>,
+      conditional_t< is_reference_v<invoke_result_t<__maybe_const<_Const, _Fn>&, range_reference_t<_View>>>,
                      conditional_t< derived_from<_Cat, contiguous_iterator_tag>, random_access_iterator_tag, _Cat >,
                      input_iterator_tag >;
 };
@@ -173,7 +173,7 @@ template <input_range _View, copy_constructible _Fn>
 #  endif
   requires __transform_view_constraints<_View, _Fn>
 template <bool _Const>
-class transform_view<_View, _Fn>::__iterator : public __transform_view_iterator_category_base<_View, _Fn> {
+class transform_view<_View, _Fn>::__iterator : public __transform_view_iterator_category_base<_View, _Fn, _Const> {
 
   using _Parent = __maybe_const<_Const, transform_view>;
   using _Base   = __maybe_const<_Const, _View>;
@@ -190,7 +190,7 @@ class transform_view<_View, _Fn>::__iterator : public __transform_view_iterator_
   iterator_t<_Base> __current_ = iterator_t<_Base>();
 
   using iterator_concept = typename __transform_view_iterator_concept<_View>::type;
-  using value_type       = remove_cvref_t<invoke_result_t<_Fn&, range_reference_t<_Base>>>;
+  using value_type       = remove_cvref_t<invoke_result_t<__maybe_const<_Const, _Fn>&, range_reference_t<_Base>>>;
   using difference_type  = range_difference_t<_Base>;
 
   _LIBCPP_HIDE_FROM_ABI __iterator()
diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp
index 25d8936f4e4eb..17340467f856b 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp
@@ -61,6 +61,21 @@ constexpr bool test() {
     static_assert(std::same_as<typename TIter::value_type, int>);
     static_assert(std::same_as<typename TIter::difference_type, std::ptrdiff_t>);
   }
+  {
+    // Member typedefs for random access iterator, LWG3564 mutable overload
+    using TView = std::ranges::transform_view<RandomAccessView, PlusOneMutableOverload>;
+    using TIter = std::ranges::iterator_t<TView>;
+    static_assert(std::same_as<typename TIter::iterator_concept, std::random_access_iterator_tag>);
+    static_assert(std::same_as<typename TIter::iterator_category, std::random_access_iterator_tag>);
+    static_assert(std::same_as<typename TIter::value_type, int>);
+    static_assert(std::same_as<typename TIter::difference_type, std::ptrdiff_t>);
+
+    using CTIter = std::ranges::iterator_t<const TView>;
+    static_assert(std::same_as<typename CTIter::iterator_concept, std::random_access_iterator_tag>);
+    static_assert(std::same_as<typename CTIter::iterator_category, std::input_iterator_tag>); // Note: this is now input_iterator_tag.
+    static_assert(std::same_as<typename CTIter::value_type, int>);
+    static_assert(std::same_as<typename CTIter::difference_type, std::ptrdiff_t>);
+  }
   {
     // Member typedefs for bidirectional iterator.
     using TView = std::ranges::transform_view<BidirectionalView, Increment>;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/types.h b/libcxx/test/std/ranges/range.adaptors/range.transform/types.h
index 14f85722a8c19..9268a977b8109 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.transform/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/types.h
@@ -137,6 +137,11 @@ struct PlusOne {
   constexpr int operator()(int x) const { return x + 1; }
 };
 
+struct PlusOneMutableOverload {
+  constexpr int operator()(int x) const { return x + 1; }
+  constexpr int& operator()(int& x) { return ++x; }
+};
+
 struct Increment {
   constexpr int& operator()(int& x) { return ++x; }
 };

>From 3fcdf5430ecd6f0a7cb3c98e2efcc5996e7376df Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Fri, 10 May 2024 17:51:27 -0400
Subject: [PATCH 2/4] [libc++][ranges] LWG3564:
 'transform_view::iterator<true>::value_type' and 'iterator_category' should
 use 'const F&'

---
 .../range.adaptors/range.transform/iterator/types.pass.cpp     | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp
index 17340467f856b..607b748ac3e4b 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp
@@ -72,7 +72,8 @@ constexpr bool test() {
 
     using CTIter = std::ranges::iterator_t<const TView>;
     static_assert(std::same_as<typename CTIter::iterator_concept, std::random_access_iterator_tag>);
-    static_assert(std::same_as<typename CTIter::iterator_category, std::input_iterator_tag>); // Note: this is now input_iterator_tag.
+    static_assert(std::same_as<typename CTIter::iterator_category,
+                               std::input_iterator_tag>); // Note: this is now input_iterator_tag.
     static_assert(std::same_as<typename CTIter::value_type, int>);
     static_assert(std::same_as<typename CTIter::difference_type, std::ptrdiff_t>);
   }

>From 33d4ed7088598149acee492d3c0f3d43cdd7a280 Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Fri, 10 May 2024 22:10:01 -0400
Subject: [PATCH 3/4] [libc++][ranges] LWG3564:
 'transform_view::iterator<true>::value_type' and 'iterator_category' should
 use 'const F&'

---
 libcxx/include/__ranges/transform_view.h | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/libcxx/include/__ranges/transform_view.h b/libcxx/include/__ranges/transform_view.h
index af973076e04f8..e52cf79fe16c9 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -153,15 +153,15 @@ struct __transform_view_iterator_concept<_View> {
   using type = forward_iterator_tag;
 };
 
-template <class, class, bool>
+template <class, class>
 struct __transform_view_iterator_category_base {};
 
-template <forward_range _View, class _Fn, bool _Const>
-struct __transform_view_iterator_category_base<_View, _Fn, _Const> {
+template <forward_range _View, class _Fn>
+struct __transform_view_iterator_category_base<_View, _Fn> {
   using _Cat = typename iterator_traits<iterator_t<_View>>::iterator_category;
 
   using iterator_category =
-      conditional_t< is_reference_v<invoke_result_t<__maybe_const<_Const, _Fn>&, range_reference_t<_View>>>,
+      conditional_t< is_reference_v<invoke_result_t<_Fn&, range_reference_t<_View>>>,
                      conditional_t< derived_from<_Cat, contiguous_iterator_tag>, random_access_iterator_tag, _Cat >,
                      input_iterator_tag >;
 };
@@ -173,7 +173,8 @@ template <input_range _View, copy_constructible _Fn>
 #  endif
   requires __transform_view_constraints<_View, _Fn>
 template <bool _Const>
-class transform_view<_View, _Fn>::__iterator : public __transform_view_iterator_category_base<_View, _Fn, _Const> {
+class transform_view<_View, _Fn>::__iterator
+    : public __transform_view_iterator_category_base<_View, __maybe_const<_Const, _Fn>> {
 
   using _Parent = __maybe_const<_Const, transform_view>;
   using _Base   = __maybe_const<_Const, _View>;

>From c2de53b48d3e3c7d0f37038535e9cca1846ffd7b Mon Sep 17 00:00:00 2001
From: Xiaoyang Liu <siujoeng.lau at gmail.com>
Date: Thu, 25 Jul 2024 05:01:28 +0900
Subject: [PATCH 4/4] [libc++][ranges] LWG3564:
 'transform_view::iterator<true>::value_type' and 'iterator_category' should
 use 'const F&'

Co-authored-by: Louis Dionne <ldionne.2 at gmail.com>
---
 libcxx/docs/Status/Cxx23Issues.csv | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index fef60d289f86f..1e0eb274d3c58 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -159,7 +159,7 @@
 "`3660 <https://wg21.link/LWG3660>`__","``iterator_traits<common_iterator>::pointer`` should conform to §[iterator.traits]","February 2022","|Complete|","14.0","|ranges|"
 "`3661 <https://wg21.link/LWG3661>`__","``constinit atomic<shared_ptr<T>> a(nullptr);`` should work","February 2022","",""
 "","","","","",""
-"`3564 <https://wg21.link/LWG3564>`__","``transform_view::iterator<true>::value_type`` and ``iterator_category`` should use ``const F&``","July 2022","|Complete|","19.0","|ranges|"
+"`3564 <https://wg21.link/LWG3564>`__","``transform_view::iterator<true>::value_type`` and ``iterator_category`` should use ``const F&``","July 2022","|Complete|","20.0","|ranges|"
 "`3617 <https://wg21.link/LWG3617>`__","``function``/``packaged_task`` deduction guides and deducing ``this``","July 2022","",""
 "`3656 <https://wg21.link/LWG3656>`__","Inconsistent bit operations returning a count","July 2022","|Complete|","15.0",""
 "`3659 <https://wg21.link/LWG3659>`__","Consider ``ATOMIC_FLAG_INIT`` undeprecation","July 2022","|Complete|","15.0"



More information about the libcxx-commits mailing list