Enlico
Enlico

Reputation: 28490

Is piping a boost::iterator_range backed up by std::list into ranges::views::transform(f) | ranges::to_vector valid code?

Here is the code:

#include <boost/range/iterator_range.hpp>
#include <functional>
#include <list>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/transform.hpp>
#include <vector>

using namespace ranges;
using namespace ranges::views;
int main()
{
    std::list<int> v;
    auto r = boost::make_iterator_range(v);
    auto w = r
           | transform([](auto x){ return x; })
           | to_vector;
}

It does not compile for , the error being copied two code snippets below.

Either of these actions makes it compile

What is the correct behavior, Clang's or GCC's, according to and ?

Here are the variations described above on Compiler Explorer.

I'm more and more convinced this is a bug in GCC. I've been told it's not, but I can't really get my head around the arguments listed from those answers.

Original question Left here because contains additional information

I've stripped an example down to the following:

#include <boost/range/iterator_range_core.hpp>
#include <list>
#include <range/v3/view/ref.hpp>

int main() {
    std::list<int> l;
    using Foo = const ranges::ref_view<boost::iterator_range<decltype(l.begin())>>&;
    ranges::_size_::has_non_member_size<Foo>;
}

which

The error starts like this, and it seems to refer to a concept that requires itself (see the first link above for the full error):

In file included from /opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/view/ref.hpp:17,
                 from <source>:3:
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/range/traits.hpp: In substitution of 'template<class R>  requires (!(has_member_size<R>) || (disable_sized_range<typename std::remove_cv<typename std::remove_reference<_Tp>::type>::type>)) && (!(has_non_member_size<R>) || (disable_sized_range<typename std::remove_cv<typename std::remove_reference<_Tp>::type>::type>)) && (forward_iterator<decltype({}(static_cast<R&& (*)()noexcept (true)>(nullptr)()))>) && (sized_sentinel_for<decltype({}(static_cast<R&& (*)()noexcept (true)>(nullptr)())), decltype({}(static_cast<R&& (*)()noexcept (true)>(nullptr)()))>) constexpr ranges::_size_::fn::_result_t<R> ranges::_size_::fn::operator()(R&&) const [with R = const ranges::ref_view<boost::iterator_range<std::_List_iterator<int> > >&]':
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/range/traits.hpp:76:47:   required by substitution of 'template<class Rng> using range_size_t = decltype (ranges::_::size(declval<Rng&>())) [with Rng = const ranges::ref_view<boost::iterator_range<std::_List_iterator<int> > >]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/meta/meta_fwd.hpp:286:18:   required by substitution of 'template<template<class ...> class C, class ... Ts>  requires  valid<C, Ts ...> struct meta::detail::defer_<C, Ts ...> [with C = ranges::range_size_t; Ts = {const ranges::ref_view<boost::iterator_range<std::_List_iterator<int> > >}]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/meta/meta.hpp:788:12:   required from 'struct meta::defer<ranges::range_size_t, const ranges::ref_view<boost::iterator_range<std::_List_iterator<int> > > >'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/view/ref.hpp:121:1:   required from 'struct boost::range_size<const ranges::ref_view<boost::iterator_range<std::_List_iterator<int> > > >'
/opt/compiler-explorer/libs/boost_1_85_0/boost/range/size.hpp:55:5:   required by substitution of 'template<class SinglePassRange> typename boost::range_size<const SinglePassRange>::type boost::size(const SinglePassRange&) [with SinglePassRange = ranges::ref_view<boost::iterator_range<std::_List_iterator<int> > >]'
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/range/primitives.hpp:63:9:   required from here
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/range/primitives.hpp:63:9:   required for the satisfaction of 'has_non_member_size_requires_<T>' [with T = const ranges::ref_view<boost::iterator_range<std::_List_iterator<int> > >&]
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/range/primitives.hpp:63:9:   in requirements with 'T&& t' [with T = const ranges::ref_view<boost::iterator_range<std::_List_iterator<int> > >&]
/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/range/primitives.hpp:63:9: error: satisfaction of atomic constraint 'requires(T&& t) {ranges::_size_::size((T&&(t)));} [with T = T]' depends on itself
   63 |         CPP_requires(has_non_member_size_,
      |         ^

Some observations:

Can somebody enlighten me on what's happening?

Upvotes: 4

Views: 140

Answers (0)

Related Questions