ericniebler / range-v3

Range library for C++14/17/20, basis for C++20's std::ranges
Other
4.15k stars 439 forks source link

With compiling with gcc >= 11.1 for C++20, constraint depending on itself when checking for member begin on constant ref_view around boost range #1823

Open Aster89 opened 4 months ago

Aster89 commented 4 months ago

Here is the code

#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_requires_<Foo>;
}

which fails to compile with GCC >= 11.1. Part of the error is copied below:

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_,
      |         ^

With each single one of the following crucial changes, the code compiles


I've at first asked the question on StackOverflow, but haven't received much feedback so far.