Skip to content

Commit e74be35

Browse files
Xiaoyang Liufrederick-vs-ja
Xiaoyang Liu
andauthored
[libc++][ranges] LWG3984: ranges::to's recursion branch may be ill-formed (#87964)
This pull request implements LWG3984: ranges::to's recursion branch may be ill-formed. In the current implementation, ranges::to's recursion branch pipes the range into a `views::transform(/* lambda */)`, which is a __range_adaptor_closure object. In libc++, the pipe operator of __range_adaptor_closure requires a viewable_range, so the following code won't compile, as the type of lvalue `r` doesn't model viewable_range: #include <ranges> #include <vector> #include <list> int main() { std::vector<std::vector<int>> v; auto r = std::views::all(std::move(v)); auto l = std::ranges::to<std::list<std::list<int>>>(r); } Co-authored-by: A. Jiang <[email protected]>
1 parent 1728a56 commit e74be35

File tree

3 files changed

+8
-2
lines changed

3 files changed

+8
-2
lines changed

libcxx/docs/Status/Cxx2cIssues.csv

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"`3919 <https://wg21.link/LWG3919>`__","``enumerate_view`` may invoke UB for sized common non-forward underlying ranges","Tokyo March 2024","","","|ranges|"
4545
"`3950 <https://wg21.link/LWG3950>`__","``std::basic_string_view`` comparison operators are overspecified","Tokyo March 2024","|Complete|","18.0",""
4646
"`3975 <https://wg21.link/LWG3975>`__","Specializations of ``basic_format_context`` should not be permitted","Tokyo March 2024","|Nothing To Do|","","|format|"
47-
"`3984 <https://wg21.link/LWG3984>`__","``ranges::to``'s recursion branch may be ill-formed","Tokyo March 2024","","","|ranges|"
47+
"`3984 <https://wg21.link/LWG3984>`__","``ranges::to``'s recursion branch may be ill-formed","Tokyo March 2024","|Complete|","19.0","|ranges|"
4848
"`4011 <https://wg21.link/LWG4011>`__","``""Effects: Equivalent to return""`` in ``[span.elem]``","Tokyo March 2024","|Nothing To Do|","",""
4949
"`4012 <https://wg21.link/LWG4012>`__","``common_view::begin/end`` are missing the ``simple-view`` check","Tokyo March 2024","","","|ranges|"
5050
"`4013 <https://wg21.link/LWG4013>`__","``lazy_split_view::outer-iterator::value_type`` should not provide default constructor","Tokyo March 2024","","","|ranges|"

libcxx/include/__ranges/to.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <__ranges/concepts.h>
2525
#include <__ranges/from_range.h>
2626
#include <__ranges/range_adaptor.h>
27+
#include <__ranges/ref_view.h>
2728
#include <__ranges/size.h>
2829
#include <__ranges/transform_view.h>
2930
#include <__type_traits/add_pointer.h>
@@ -129,7 +130,7 @@ template <class _Container, input_range _Range, class... _Args>
129130
// Try the recursive case.
130131
} else if constexpr (input_range<range_reference_t<_Range>>) {
131132
return ranges::to<_Container>(
132-
__range | views::transform([](auto&& __elem) {
133+
ref_view(__range) | views::transform([](auto&& __elem) {
133134
return ranges::to<range_value_t<_Container>>(std::forward<decltype(__elem)>(__elem));
134135
}),
135136
std::forward<_Args>(__args)...);

libcxx/test/std/ranges/range.utility/range.utility.conv/to.pass.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,11 @@ constexpr void test_recursive() {
560560
}
561561

562562
assert((in | std::ranges::to<C4>()) == result);
563+
564+
// LWG3984: ranges::to's recursion branch may be ill-formed
565+
auto in_owning_view = std::views::all(std::move(in));
566+
static_assert(!std::ranges::viewable_range<decltype((in_owning_view))>);
567+
assert(std::ranges::to<C4>(in_owning_view) == result);
563568
}
564569

565570
constexpr bool test() {

0 commit comments

Comments
 (0)