This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of WP status.

### 3574. `common_iterator` should be completely `constexpr`-able

Section: 25.5.5.1 [common.iterator] Status: WP Submitter: Hewill Kang Opened: 2021-07-21 Last modified: 2021-10-14

Priority: 3

View all other issues in [common.iterator].

View all issues with WP status.

Discussion:

After P2231R1, `variant` becomes completely `constexpr`-able, which means that `common_iterator` can also be completely `constexpr`-able.

[2021-08-20; Reflector poll]

Set priority to 3 after reflector poll.

[2021-08-23; Reflector poll]

Set status to Tentatively Ready after five votes in favour during reflector poll.

[2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP.]

Proposed resolution:

This wording is relative to N4892.

1. Modify 25.5.5.1 [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(I i);
   >         constexpr common_iterator(S s);
   >         template<class I2, class S2>
   >           requires convertible_to<const I2&, I> && convertible_to<const S2&, S>
   >             constexpr common_iterator(const common_iterator<I2, S2>& x);

   >         template<class I2, class S2>
   >           requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
   >                    assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
   >           constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);

   >         constexpr decltype(auto) operator*();
   >         constexpr decltype(auto) operator*() const
   >           requires dereferenceable<const I>;
   >         constexpr decltype(auto) operator->() const
   >           requires see below;

   >         constexpr common_iterator& operator++();
   >         constexpr decltype(auto) operator++(int);

   >         template<class I2, sentinel_for<I> S2>
   >           requires sentinel_for<S, I2>
   >         friend constexpr bool operator==(
   >           const common_iterator& x, const common_iterator<I2, S2>& y);
   >         template<class I2, sentinel_for<I> S2>
   >           requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
   >         friend constexpr bool operator==(
   >           const common_iterator& x, const common_iterator<I2, S2>& y);

   >         template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
   >           requires sized_sentinel_for<S, I2>
   >         friend constexpr iter_difference_t<I2> operator-(
   >           const common_iterator& x, const common_iterator<I2, S2>& y);

   >         friend constexpr iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
   >           noexcept(noexcept(ranges::iter_move(declval<const I&>())))
   >             requires input_iterator<I>;
   >         template<indirectly_swappable<I> I2, class S2>
   >           friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
   >             noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));

   >       private:
   >         variant<I, S> v_; // exposition only
   >       };
   >       […]
   >     }

2. Modify 25.5.5.3 [common.iter.const] as indicated:

   >     template<class I2, class S2>
   >       requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
   >                assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
   >         constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);

   > > -5- Preconditions: `x.v_.valueless_by_exception()` is `false`.

   > > […]

3. Modify 25.5.5.4 [common.iter.access] as indicated:

   >     constexpr decltype(auto) operator*();
   >     constexpr decltype(auto) operator*() const
   >       requires dereferenceable<const I>;

   > > -1- Preconditions: `holds_alternative<I>(v_)` is `true`.

   > > […]

   >     constexpr decltype(auto) operator->() const
   >       requires see below;

   > > -3- The expression in the requires-clause is equivalent to:

   > > […]

4. Modify 25.5.5.5 [common.iter.nav] as indicated:

   >     constexpr common_iterator& operator++();

   > > -1- Preconditions: `holds_alternative<I>(v_)` is `true`.

   > > […]

   >     constexpr decltype(auto) operator++(int);

   > > -4- Preconditions: `holds_alternative<I>(v_)` is `true`.

   > > […]

5. Modify 25.5.5.6 [common.iter.cmp] as indicated:

   >     template<class I2, sentinel_for<I> S2>
   >       requires sentinel_for<S, I2>
   >     friend constexpr bool operator==(
   >       const common_iterator& x, const common_iterator<I2, S2>& y);

   > > -1- Preconditions: […]

   >     template<class I2, sentinel_for<I> S2>
   >       requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
   >     friend constexpr bool operator==(
   >       const common_iterator& x, const common_iterator<I2, S2>& y);

   > > -3- Preconditions: […]

   >     template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
   >       requires sized_sentinel_for<S, I2>
   >     friend constexpr iter_difference_t<I2> operator-(
   >       const common_iterator& x, const common_iterator<I2, S2>& y);

   > > -5- Preconditions: […]

6. Modify 25.5.5.7 [common.iter.cust] as indicated:

   >     friend constexpr iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
   >       noexcept(noexcept(ranges::iter_move(declval<const I&>())))
   >         requires input_iterator<I>;

   > > -1- Preconditions: […]

   >     template<indirectly_swappable<I> I2, class S2>
   >       friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
   >         noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));

   > > -3- Preconditions: […]