On Mon, Sep 30, 2024 at 3:43 AM Avi Kivity <avi@scylladb.com> wrote:
On Sun, 2024-09-29 at 16:00 -0500, Barry Revzin via Std-Proposals wrote:


On Sun, Sep 29, 2024 at 3:32 PM Arthur O'Dwyer via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Sun, Sep 29, 2024 at 3:26 PM Avi Kivity via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
I find it common to want to constrain a range to return a particular type. Something like

    void f(std::ranges::range_of<unsigned> auto&& range_of_unsigned) { ... }

It would be trivial to define such a concept, or to forego the abbreviated template syntax and use a requires clause, but it seems to me this should be a vocabulary concept.
There's the question of whether the type should be same_as or convertible_to, perhaps there is room for two concepts here.


This sounds like the same thing (in practice) as the exposition-only container-compatible-range.


The problem with range_of is what exactly that should mean. Should range_of<unsigned> actually match any range of integral (i.e. convertible_to) or just specifically ranges of prvalue unsigned (i.e. same_as)? But same_as wouldn't even match vector<unsigned>, so if you want that did you actually want same_as but matching on value_type instead? Or decays_to?

Why would same_as not match vector<unsigned>? Of course we'd match value_type, not the range itself.

Not the range itself, but the range's reference type (as in the link concept above). The range's reference type is what most code interacts with unless it explicitly needs to create a value, so I don't think it is "of course" that we'd match the value_type. And the reference type of vector<unsigned> is either unsigned& or unsigned const&, depending on whether the vector is const.
 



So... sure, container-compatible-range is one of those things. But the problem with range_of<T> is what exactly you wanted to check your T against.
 

We'd just have two concepts. Maybe range_of (with convertible_to matching, used for reads) and range_of_exactly (used for writes). I'd say range_of is much more useful.

If we had associated types, then we wouldn't have any concepts - you'd just write input_range<.value_type = unsigned> or input_range<.value_type : convertible_to<unsigned>> depending on what you actually wanted. Otherwise, there's a lot of potential concepts in this space.

Barry