Instead of storing the wrapped iterator inside the stride_counting_iterator,
store its base so we can have e.g. a stride_counting_iterator of an
input_iterator (which was previously impossible because input_iterators
are not copyable).
As a fly-by fix, remove the member base() functions, which are super
confusing.
This is the only place iterator_concept_t is used. Could we change this to something like
using iterator_concept = std::conditional_t< std::contiguous_iterator<It>, std::contiguous_iterator_tag, std::conditional_t< std::random_access_iterator<It>, std::random_access_iterator_tag, std::conditional_t< std::bidirectional_iterator<It>, std::bidirectional_iterator_tag, std::conditional_t< std::forward_iterator<It>, std::forward_iterator_tag, std::conditional_t< std::input_iterator<It>, std::input_iterator_tag, std::output_iterator_tag >>>>>;and then eliminate lines 649–689?
Alternatively, is it possible to replace the whole thing with just
or does that fail tests such as
? (This would all be much easier if ITER-CONCEPT were a real thing instead of being exposition-only.)