Is there a class to store a generic range in std::ranges?

Viewed 147

Is there a concrete template class (not a concept) to store a generic range (i.e. pair of iterators/sentinels) in std Ranges?

Given a pair of iterator I can always store it in std::pair<iterator_type, interator_type> and access to them as .first and .second, but in reality they could be named .begin() and .end().

I found this very old proposal, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3350.html#index_1overview

The reason is that I have function that takes a pair of iterators (as in the old days) and should return a (const) view of them, so it seem that I need to return a concrete type.

template<class It>
a_range<It> my_func(It first, It last){
   ...
   return a_range<It>(first, last);
}

I didn't find anything in the Range library. The closest I could find is https://en.cppreference.com/w/cpp/ranges/view_interface.

template<class It>
auto my_func(It first, It last){
   ...
   struct View : public std::ranges::view_interface<View> {
     View(It begin, It end) : m_begin(begin), m_end(){}
     auto begin() const { return m_begin; }
     auto end() const { return m_end; }
   private:
     It m_begin, m_end;
   };
   return View{first, last};
}

or, more to the point:

   ...
   return  std::ranges::transform_view{ View{first, last}, [](auto const& a)->decltype(a){return a;});
}

Is this going in the right direction?

To begin with, I would like to keep access category (e.g. random access, etc), which this doesn't seem to preserve. Also using transform to protect (as const) the elements seems an overkill, but that is secondary.

1 Answers

I think you're asking for a range that can be created from a pair of iterators (or more generally, iterator and sentinel). std::ranges::subrange does that. It inherits from view_interface that you mentioned.

Related