C++ Logo

std-proposals

Advanced search

Re: [std-proposals] ranges::to() should prefer iterator_concept over iterator_category

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Mon, 2 Sep 2024 11:57:15 +0100
On Mon, 2 Sept 2024 at 11:56, Vesselin Atanasov <vesselin.atanasov_at_[hidden]>
wrote:

> OK, thank you for the clarification. I guess I will have to use some
> workaround for the time being until libstdc++ adds the missing
> constructors.
>

... or contribute the missing constructors to libstdc++ :-)



>
> Regards
>
> On Mon, 2024-09-02 at 09:21 +0100, Jonathan Wakely wrote:
> >
> >
> > On Mon, 2 Sept 2024, 04:42 Vesselin Atanasov via Std-Proposals,
> > <std-proposals_at_[hidden]> wrote:
> > > Hello,
> > >
> > > The current C++ standard draft provides a description of
> > > ranges:to(),
> > > which among other things says:
> > >
> > > -------------------------------------------
> > > 26.5.7.2 ranges::to
> > > ...
> > > (2.1.3) Otherwise, if
> > > (2.1.3.1) common_range<R> is true,
> > > (2.1.3.2) the qualified-id
> > > iterator_traits<iterator_t<R>>::iterator_category is valid and
> > > denotes a type that models derived_from<input_iterator_tag>, and
> > > (2.1.3.3) constructible_from<C, iterator_t<R>, sentinel_t<R>,
> > > Args...> is true:
> > >
> > > C(ranges::begin(r), ranges::end(r), std::forward<Args>(args)...)
> > > -------------------------------------------
> > >
> > > However there are quite a few cases of valid C++20 input iterators
> > > that
> > > are NOT valid C++17 input iterators, because their post-increment
> > > operator returns void. Such input iterators have the
> > > iterator_concept
> > > typedef but don't have the iterator_category typedef.
> > >
> > > So if ranges::to() is passed an input range with such an input
> > > iterator, it won't be able to construct the container using:
> > >
> > > C(ranges::begin(r), ranges::end(r), std::forward<Args>(args)...)
> > >
> > > even though in theory it could if it checked for the
> > > iterator_concept
> > > typedef.
> > >
> > > For us who use GCC this problem is additionally aggravated by the
> > > fact
> > > that GCC's libstdc++ has not implemented
> > > P1206R7, Conversions from ranges to containers
> > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111055
> > > So ranges::to() cannot construct the container directly from the
> > > range
> > > object.
> > >
> > > And additionally constructing an associative container fails when
> > > ranges::to() tries to do that via append, because it calls
> > > emplace()
> > > with the wrong arguments.
> > >
> > > What I suggest is amending slightly the way ranges::to() works when
> > > it
> > > tries to create a container from an iterator+sentinel pair. It
> > > should
> > > check first the iterator_concept typedef and if it is missing then
> > > it
> > > should check the iterator_category typedef. This way it will be
> > > able to
> > > use C++20 input iterators that are not C++17 input iterators.
> >
> > This doesn't work, because the constructor that you want to use is
> > defined in terms of C++17 input iterators. If you pass it arguments
> > that are not C++17 input iterators, it might not work.
> >
> > The correct constructor for this case it's the one that takes the
> > from_range tag. We should not change the standard to work around
> > missing features in libstdc++. Somebody just needs to add those
> > constructors.
> >
> >
> >
>
>

Received on 2024-09-02 10:58:34