Reputation: 347
I want to upgrade my custom container to compatible with std::ranges
algorithms such as find_if
and others, like bellow
auto is_satisfy = [](CustomContainer::value_type x) { ... };
std::ranges::find_if(custom_container, is_satisfy);
// instead of std::find_if(custom_container.begin(), custom_container.end(), is_satisfy);
Signature of std::ranges::find_if
like as
struct find_if_fn {
template< ranges::input_range R,
class Proj = std::identity,
std::indirect_unary_predicate<std::projected<ranges::iterator_t<R>,
Proj>> Pred >
constexpr ranges::borrowed_iterator_t<R>
operator()( R&& r, Pred pred = {}, Proj proj = {} ) const
{
return (*this)(ranges::begin(r), ranges::end(r), std::ref(pred), std::ref(proj));
}
};
What is the input_range concept and how this feature is supported by my own custom container?
Upvotes: 3
Views: 206
Reputation: 238351
What is the input_range concept
It is this:
template<class T> concept input_range = range<T> && input_iterator<iterator_t<T>>;
In English, input_range is a range whose iterator is an input_iterator. The range concept on the other hand is:
The range concept defines the requirements of a type that allows iteration over its elements by providing an iterator and sentinel that denote the elements of the range.
template<class T> concept range = requires(T& t) { ranges::begin(t); // sometimes equality-preserving ranges::end(t); };
And input_iterator is:
The input_iterator concept defines requirements for a type whose referenced values can be read (from the requirement for indirectly_readable ([iterator.concept.readable])) and which can be both pre- and post-incremented. [Note 1: Unlike the Cpp17InputIterator requirements ([input.iterators]), the input_iterator concept does not need equality comparison since iterators are typically compared to sentinels. — end note]
template<class I> concept input_iterator = input_or_output_iterator<I> && indirectly_readable<I> && requires { typename ITER_CONCEPT(I); } && derived_from<ITER_CONCEPT(I), input_iterator_tag>;
You can go read the specs for the dependee concepts, functions and traits for exact details.
how this feature is supported by my own custom container?
In short: By conforming to the concepts shown above.
In medium: Provide member functions begin
and end
of which former should return an input iterator and latter should return a compatible sentinel type (which may be same or different from the iterator type). The end sentinel should be reachable from the beginning and represents one past the last element of the range.
In general, I recommend looking at API of standard containers to find out what members they provide and how they work. Copy the design to your custom containers.
Quotes are from the latest standard draft.
Upvotes: 4