This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Allow an output_iterator in fill.
AbandonedPublic

Authored by Mordante on Mar 19 2022, 10:56 AM.

Details

Reviewers
ldionne
Group Reviewers
Restricted Project
Summary

This isn't required by the Standard but is an QoI extension.

This extension isn't only benificial for users but avoids code
duplication libc++. The ouput iterator in std::format only needs to
satisfy the output_iterator concept and not the Cpp17OutputIterator
requirements. This means a conforming std::format implementation can't
use the available algorithms and needs to write their own.

Note: This is the first patch, there will be follow-up patches making
this change to other algorithms.

Depends on D122072

Diff Detail

Event Timeline

Mordante created this revision.Mar 19 2022, 10:56 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 19 2022, 10:56 AM
Mordante requested review of this revision.Mar 19 2022, 10:56 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 19 2022, 10:56 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript

Would ranges::fill_n work for your purposes? If yes, maybe just use that (I can work on implementing it) instead of adding an extension?

Would ranges::fill_n work for your purposes? If yes, maybe just use that (I can work on implementing it) instead of adding an extension?

Good point, when I initially ran into this issue ranges was quite less mature so I never even considered it. But it should be possible.
If you want to look into it that would be great! From a quick look at the format code I use copy, copy_n, fill_n, and transform.

The copy and copy_n are a bit tricky due to the wrap_iterator.

@ldionne Do you see any value in this extension or do you prefer to abandon this patch?

Interesting patch! On the one hand I don't really want to commit to this extension (extensions are evil!), however it does seem to me like moving instead of copying the iterator is an improvement, and it's trivial to do. It's also clearly conforming.

This leads me to wonder whether the standard could relax those restrictions itself. Would you have any interest in investigating that with a short paper?

I would suggest one of two things for the time being:

  1. Either you add std::move to std::fill and start using it in <format>, but you put the rest of this patch on the ice until we have clarity about relaxing this in the Standard (i.e. you don't add tests or documentation that would commit us to an extension), or
  2. You use ranges::fill instead in <format> and you put this patch on the ice until we have clarity, or you abandon it.

In other words, if you want to keep using std::fill instead of ranges::fill in <format>, I would be fine with relaxing the requirement as an implementation detail in std::fill, but not to commit to the extension until we have clarity about doing it in the Standard per se. I hope this makes sense?

libcxx/test/std/algorithms/alg.modifying.operations/alg.fill/fill_n.pass.cpp
151
162
Mordante planned changes to this revision.Mar 23 2022, 1:24 PM

Thanks for the feedback!
In that case I put this patch on hold. In format I'm not only using fill, but several other algorithms like copy and transform. So only doing one algorithm makes little sense. I only did this one patch to float the idea. Especially copy is a more effort due to the wrap iterator.

As mentioned on Discord when I started to work on this patch these algorithms in ranges were still far off, now they are not that far off. When I restarted working on it recently I didn't really think about the ranges versions anymore until @philnik asked an excellent question.

I like your suggestion about writing a paper. I was surprised these iterators in <algorithm> didn't change in C++20. But I can't recall seeing a paper suggesting this direction. I'll have a look whether there has been a paper, if not I will consider writing one.

Mordante abandoned this revision.Sep 28 2022, 12:14 PM

With ranges completed there's no need to use pre-C++20 algorithms. Since it will be quite a bit of effort to adjust all algorithms and it has a very low priority I abandon this instead.