cplusplus / draft

C++ standards drafts
http://www.open-std.org/jtc1/sc22/wg21/
5.69k stars 749 forks source link

Replace boilerplate for deciding iterator_category of a view adaptor's iterator #4692

Open jwakely opened 3 years ago

jwakely commented 3 years ago

Several iterator types for view adaptors have wording like this (from [range.filter.iterator]):

iterator::iterator_category is defined as follows:

  • Let C denote the type iterator_traits<iterator_t<V>>::iterator_category.
  • If C models derived_from<bidirectional_iterator_tag>, then iterator_category denotes bidirectional_iterator_tag.
  • Otherwise, if C models derived_from<forward_iterator_tag>, then iterator_category denotes forward_iterator_tag.
  • Otherwise, iterator_category denotes C.

We could avoid the repetition with an exposition-only helper along the lines of:

template<class C, class... Cats>
  struct floor-cat
 { using type = C; };
template<class C, class Cat, class... Cats>
  struct floor-cat
  : conditional<derived_from<C, Cat>, Cat, floor-cat<C, Cats...>>
 { };
template<class T, class... Cats>
  using floor-cat-t = typename floor-cat<T, Cats...>::type;

And then define iterator::iterator_category for the example above as floor-cat<iterator_traits<iterator_t<V>>::iterator_category, bidirectional_iterator_tag, forward_iterator_tag>.

JohelEGP commented 2 years ago

Ping for the de-duplication train.