Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions libcxx/include/__ranges/to.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,11 @@ template <class _Container, input_range _Range, class... _Args>
__result.reserve(static_cast<range_size_t<_Container>>(ranges::size(__range)));
}

for (auto&& __ref : __range) {
using _Ref = decltype(__ref);
auto __iter = ranges::begin(__range);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest we use ranges::for_each instead, that seems cleaner and I don't think saving an include dependency is worth the added code complexity.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also wonder whether this would improve interactions with deque iterators.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to use ranges::for_each. I wonder whether range-for on ref_view{__range} suffices.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is somehow bad, as encountered in #113103 (comment).

auto __sent = ranges::end(__range);
for (; __iter != __sent; ++__iter) {
auto&& __ref = *__iter;
using _Ref = decltype(__ref);
if constexpr (requires { __result.emplace_back(std::declval<_Ref>()); }) {
__result.emplace_back(std::forward<_Ref>(__ref));
} else if constexpr (requires { __result.push_back(std::declval<_Ref>()); }) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,11 +550,30 @@ constexpr void test_recursive() {
assert(std::ranges::to<C4>(in_owning_view) == result);
}

struct adl_only_range {
static constexpr int numbers[2]{42, 1729};

void begin() const = delete;
void end() const = delete;

friend constexpr const int* begin(const adl_only_range&) { return std::ranges::begin(numbers); }
friend constexpr const int* end(const adl_only_range&) { return std::ranges::end(numbers); }
};

constexpr void test_lwg4016_regression() {
using Cont = Container<int, CtrChoice::DefaultCtrAndInsert, InserterChoice::PushBack, true>;

std::ranges::contiguous_range auto r = adl_only_range{};
auto v = r | std::ranges::to<Cont>();
assert(std::ranges::equal(v, adl_only_range::numbers));
}

constexpr bool test() {
test_constraints();
test_ctr_choice_order();
test_lwg_3785();
test_recursive();
test_lwg4016_regression();

return true;
}
Expand Down
Loading