Title
views::common may not be a range adaptor object
Status
new
Section
[common.iterator][common.iter.cmp]
Submitter
Hewill Kang

Created on 2022-09-18.00:00:00 last changed 18 months ago

Messages

Date: 2022-09-28.20:08:32

Proposed resolution:

This wording is relative to N4917.

  1. Modify [common.iterator], class template common_iterator synopsis, as indicated:

    namespace std {
      template<input_or_output_iterator I, sentinel_for<I> S>
        requires (!same_as<I, S> && copyable<I>)
      class common_iterator {
      public:
        constexpr common_iterator() requires default_initializable<I> = default;
        constexpr common_iterator();
        […]
      };
      […]
    }
    
  2. Modify [common.iter.const] as indicated:

    constexpr common_iterator();
    

    -?- Effects: Initializes v_ as if by v_{in_place_type<S>}.

    constexpr common_iterator(I i);
    

    -1- Effects: Initializes v_ as if by v_{in_place_type<I>, std::move(i)}.

Date: 2022-09-15.00:00:00

[ 2022-09-28; Reflector poll ]

Set priority to 3 after reflector poll.

"The P/R means that sometimes the variant containers an iterator and sometimes contains a sentinel, depending on whether the iterator is default constructible. Always constructing a sentinel would be more consistent."

Date: 2022-09-18.13:46:18

P2325R3 makes input_or_output_iterator no longer require default_initializable, which means that the template parameter I of common_iterator no longer requires default_initializable.

In this case, since common_iterator itself cannot be default-constructed, it can never be a valid sentinel even if it can be compared to itself. Furthermore, this also makes views::common return a non-range even if it is well-formed (online example):

#include <ranges>
#include <vector>

int main() {
  std::vector<int> v;
  auto r = std::views::counted(std::back_inserter(v), 3);
  auto cr = r | std::views::common;
  static_assert(std::ranges::range<decltype(cr)>); // failed
}

which causes views::common to be unable to convert a range into a view, making it not a valid range adaptor.

I think common_iterator should always be default_initializable, which makes it eligible to be a legitimate sentinel.

The proposed resolution provides a default constructor for common_iterator when I is not default_initializable, in which case constructs the variant with an alternative type of S.

History
Date User Action Args
2022-09-28 20:08:32adminsetmessages: + msg12830
2022-09-18 09:02:27adminsetmessages: + msg12780
2022-09-18 00:00:00admincreate