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.

### 3702. Should `zip_transform_view::iterator` remove `operator<`?

Section: 26.7.24.3 [range.zip.transform.iterator] Status: WP Submitter: Hewill Kang Opened: 2022-05-21 Last modified: 2022-07-25

Priority: Not Prioritized

View all issues with WP status.

Discussion:

After LWG 3692, `zip_view::iterator` only provides `operator<=>`. Since the comparison of `zip_transform_view::iterator` uses `zip_view::iterator`'s `operator<=>`, it is possible to remove `zip_transform_view::iterator`'s `operator<`, `>`, `<=`, `>=` and just detect if `ziperator`'s `operator<=>` is available.

Since the `ziperator`'s `operator<=>` is valid only when `zip_view` is a `random_access_range`, we don't need to additionally constrain the `ziperator` to be `three_way_comparable`.

[2022-06-21; Reflector poll]

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

[2022-07-15; LWG telecon: move to Ready]

[2022-07-25 Approved at July 2022 virtual plenary. Status changed: Ready → WP.]

Proposed resolution:

This wording is relative to N4910.

1. Modify 26.7.24.3 [range.zip.transform.iterator] as indicated:

   > >     namespace std::ranges {
   > >     […]
   > >     template<copy_constructible F, input_range... Views>
   > >     requires (view<Views> && ...) && (sizeof...(Views) > 0) && is_object_v<F> &&
   > >              regular_invocable<F&, range_reference_t<Views>...> &&
   > >              can-reference<invoke_result_t<F&, range_reference_t<Views>...>>
   > >     template<bool Const>
   > >     class zip_transform_view<F, Views...>::iterator {
   > >       using Parent = maybe-const<Const, zip_transform_view>;        // exposition only
   > >       using Base = maybe-const<Const, InnerView>;                   // exposition only
   > >       Parent* parent_ = nullptr;                                    // exposition only
   > >       ziperator<Const> inner_;                                      // exposition only

   > >       constexpr iterator(Parent& parent, ziperator<Const> inner);   // exposition only
   > >     public:
   > >       […]
   > >       friend constexpr bool operator==(const iterator& x, const iterator& y)
   > >         requires equality_comparable<ziperator<Const>>;

   > >       friend constexpr bool operator<(const iterator& x, const iterator& y)
   > >         requires random_access_range<Base>;
   > >       friend constexpr bool operator>(const iterator& x, const iterator& y)
   > >         requires random_access_range<Base>;
   > >       friend constexpr bool operator<=(const iterator& x, const iterator& y)
   > >         requires random_access_range<Base>;
   > >       friend constexpr bool operator>=(const iterator& x, const iterator& y)
   > >         requires random_access_range<Base>;
   > >       friend constexpr auto operator<=>(const iterator& x, const iterator& y)
   > >         requires random_access_range<Base>&& three_way_comparable<ziperator<Const>>;
   > >       […]
   > >     };
   > >     […]
   > >     }

   > […]

   >     friend constexpr bool operator==(const iterator& x, const iterator& y)
   >       requires equality_comparable<ziperator<Const>>;
   >     friend constexpr bool operator<(const iterator& x, const iterator& y)
   >       requires random_access_range<Base>;
   >     friend constexpr bool operator>(const iterator& x, const iterator& y)
   >       requires random_access_range<Base>;
   >     friend constexpr bool operator<=(const iterator& x, const iterator& y)
   >       requires random_access_range<Base>;
   >     friend constexpr bool operator>=(const iterator& x, const iterator& y)
   >       requires random_access_range<Base>;
   >     friend constexpr auto operator<=>(const iterator& x, const iterator& y)
   >       requires random_access_range<Base>&& three_way_comparable<ziperator<Const>>;

   > > -14- Let `op` be the operator.

   > > -15- Effects: Equivalent to: `return x.inner_ op y.inner_;`