CaseyCarter / cmcstl2

An implementation of C++ Extensions for Ranges
Other
221 stars 68 forks source link

Constraint recursion in any_iterator #283

Open CaseyCarter opened 5 years ago

CaseyCarter commented 5 years ago

I am compiling D:\Git\cmcstl2\test\iterator\any_iterator.cpp.

It can be triggered via:

stl2::iter_difference_t<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &, int, int &&> > >;

The (reversed) processing order is:

D:\Git\cmcstl2\include\stl2/detail/iterator/increment.hpp(61): error C2968: 'iter_difference_t<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> > >': recursive alias declaration

D:\Git\cmcstl2\include\stl2/detail/iterator/concepts.hpp(375): note: see reference to variable template 'bool WeaklyIncrementable<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> > >' being compiled

D:\Git\cmcstl2\include\stl2/detail/iterator/concepts.hpp(443): note: see reference to variable template 'bool Iterator<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> > >' being compiled

D:\Git\cmcstl2\include\stl2/detail/iterator/any_iterator.hpp(189): note: see reference to variable template 'bool InputIterator<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> > >' being compiled

D:\Git\cmcstl2\include\stl2/detail/concepts/object/move_constructible.hpp(41): note: see reference to variable template 'const bool is_constructible_v<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::any_iterator::cursor<int &,int,int &&> >,std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::any_iterator::cursor<int &,int,int &&> > &>' being compiled

D:\Git\cmcstl2\include\stl2/detail/concepts/object/semiregular.hpp(30): note: see reference to variable template 'bool Constructible<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::any_iterator::cursor<int &,int,int &&> >,std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::any_iterator::cursor<int &,int,int &&> > &>' being compiled

D:\Git\cmcstl2\include\stl2/detail/concepts/object/semiregular.hpp(39): note: see reference to variable template 'bool CopyConstructible<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> > >' being compiled

D:\Git\cmcstl2\include\stl2/detail/concepts/object/semiregular.hpp(45): note: see reference to variable template 'bool Copyable<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> > >' being compiled

D:\Git\cmcstl2\include\stl2/detail/iterator/basic_iterator.hpp(200): note: see reference to variable template 'bool Semiregular<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> > >' being compiled

D:\Git\cmcstl2\include\stl2/detail/iterator/basic_iterator.hpp(206): note: see reference to variable template 'bool Sentinel<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> >,std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> >' being compiled

D:\Git\cmcstl2\include\stl2/detail/iterator/basic_iterator.hpp(977): note: see reference to variable template 'bool SizedSentinel<std::experimental::ranges::v1::basic_iterator<std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> >,std::experimental::ranges::v1::__any_iterator::cursor<int &,int,int &&> >' being compiled

D:\Git\cmcstl2\include\stl2/detail/iterator/concepts.hpp(537): note: see reference to alias template instantiation 'std::experimental::ranges::v1::iter_difference_t' being compiled

D:\Git\cmcstl2\include\stl2/detail/iterator/operations.hpp(116): note: while compiling class template member function 'I std::experimental::ranges::v1::__next_fn::operator ()(I,incrementable_traits::difference_type) const'

The compiler first tries to see whether the following function is a valid candidate and evaluating ‘SizedSentinel’:

   template<class C, class S>

   requires cursor::SizedSentinel<S, C>

   constexpr cursor::difference_type_t<C> operator-(

          const S& lhs, const basic_iterator<C>& rhs)

   STL2_NOEXCEPT_RETURN(

          get_cursor(rhs).distance_to(lhs)

   )

Semiregular then tries to see whether S is copy constructible:

          template<class S, class C>

          META_CONCEPT SizedSentinel =

                  Sentinel<S, C> &&

                  requires(const C& c, const S& s) {

                         { c.distance_to(s) } -> Same<difference_type_t<C>>COMPOUND_REQUIREMENT_RREF;

                  };

          template<class S, class C>

          META_CONCEPT Sentinel =

                  Cursor<C> &&

                  Semiregular<S> &&

                  requires(const C& c, const S& s) {

                         { c.equal(s) } -> bool;

                  };

Then end up trying this ctor of basic_iterator (inherited from cursor::mixin):

template explicit mixin(I i)

InputIterator circular references back to the iter_difference_t:

   template<class I>

   META_CONCEPT WeaklyIncrementable =

          Semiregular<I> &&

          requires(I i) {

                  typename iter_difference_t<I>;

                  requires SignedIntegral<iter_difference_t<I>>;

ifdef WORKAROUND_COMPOUND_REQUIREMENT

                  { ++i } -> Same<I&>;

else

                  { ++i } -> Same<I>&; // not required to be equality-preserving

endif

                  i++; // not required to be equality-preserving

          };

   template<class I>

   META_CONCEPT Iterator =

          __dereferenceable<I&> && WeaklyIncrementable<I>;

          // Axiom?: i is non-singular iff it denotes an element

          // Axiom?: if i equals j then i and j denote equal elements

          // Axiom?: I{} is in the domain of copy/move construction/assignment

          //        (This should probably be a requirement of the object concepts,

          //         or at least Semiregular.)
tcbrindle commented 5 years ago

Wait, MSVC has a concepts implementation?

CaseyCarter commented 5 years ago

Wait, MSVC has a concepts implementation?

Part of one, anyway, under /experimental:concepts. I don't think the release compiler can do anything useful yet.