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

via libcxx-commits libcxx-commits at lists.llvm.org
Mon Aug 12 10:30:50 PDT 2024


Author: Xiaoyang Liu
Date: 2024-08-12T19:30:47+02:00
New Revision: d9caea18f946390e0b458471cdc3e3252099c1cf

URL: https://github.com/llvm/llvm-project/commit/d9caea18f946390e0b458471cdc3e3252099c1cf
DIFF: https://github.com/llvm/llvm-project/commit/d9caea18f946390e0b458471cdc3e3252099c1cf.diff

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

## Introduction

This patch implements LWG3564:
`transform_view::iterator<true>::value_type` and `iterator_category`
should use `const F&`.

`transform_view`'s iterator currently obtained from a `const
transform_view` invoke the transformation function as `const`, but the
`value_type` and `iterator_category` determination uses non-`const`
`F&`.

## Reference

-
[[range.transform.iterator]](https://eel.is/c++draft/range.transform.iterator)
- [LWG3564](https://cplusplus.github.io/LWG/issue3564)

Added: 
    

Modified: 
    libcxx/docs/Status/Cxx23Issues.csv
    libcxx/include/__ranges/transform_view.h
    libcxx/test/std/ranges/range.adaptors/range.transform/iterator/types.pass.cpp
    libcxx/test/std/ranges/range.adaptors/range.transform/types.h

Removed: 
    


################################################################################
diff  --git a/libcxx/docs/Status/Cxx23Issues.csv b/libcxx/docs/Status/Cxx23Issues.csv
index c4c6a855cc517b..b6381f86323dbd 100644
--- a/libcxx/docs/Status/Cxx23Issues.csv
+++ b/libcxx/docs/Status/Cxx23Issues.csv
@@ -159,7 +159,7 @@
 "`LWG3660 <https://wg21.link/LWG3660>`__","``iterator_traits<common_iterator>::pointer`` should conform to ยง[iterator.traits]","February 2022","|Complete|","14.0","|ranges|"
 "`LWG3661 <https://wg21.link/LWG3661>`__","``constinit atomic<shared_ptr<T>> a(nullptr);`` should work","February 2022","","",""
 "","","","","",""
-"`LWG3564 <https://wg21.link/LWG3564>`__","``transform_view::iterator<true>::value_type`` and ``iterator_category`` should use ``const F&``","July 2022","","","|ranges|"
+"`LWG3564 <https://wg21.link/LWG3564>`__","``transform_view::iterator<true>::value_type`` and ``iterator_category`` should use ``const F&``","July 2022","|Complete|","20.0","|ranges|"
 "`LWG3617 <https://wg21.link/LWG3617>`__","``function``/``packaged_task`` deduction guides and deducing ``this``","July 2022","","",""
 "`LWG3656 <https://wg21.link/LWG3656>`__","Inconsistent bit operations returning a count","July 2022","|Complete|","15.0",""
 "`LWG3659 <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 bcce389c0e6809..686a2a8fe8c21e 100644
--- a/libcxx/include/__ranges/transform_view.h
+++ b/libcxx/include/__ranges/transform_view.h
@@ -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> {
+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>;
@@ -190,7 +191,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 
diff erence_type  = range_
diff erence_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 25d8936f4e4ebd..607b748ac3e4bd 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,22 @@ constexpr bool test() {
     static_assert(std::same_as<typename TIter::value_type, int>);
     static_assert(std::same_as<typename TIter::
diff erence_type, std::ptr
diff _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::
diff erence_type, std::ptr
diff _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::
diff erence_type, std::ptr
diff _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 cc5679f229de25..e94e7dfcdaeb7e 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.transform/types.h
+++ b/libcxx/test/std/ranges/range.adaptors/range.transform/types.h
@@ -131,6 +131,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; }
 };


        


More information about the libcxx-commits mailing list