std::ranges::subrange

From cppreference.com
< cpp‎ | ranges
 
 
Ranges library
Views
subrange

Range adaptors
 
 
Defined in header <ranges>
template<

    std::input_or_output_iterator I,
    std::sentinel_for<I> S = I,
    ranges::subrange_kind K = std::sized_sentinel_for<S, I> ?
                                  ranges::subrange_kind::sized :
                                  ranges::subrange_kind::unsized
>
    requires (K == ranges::subrange_kind::sized ||
                 !std::sized_sentinel_for<S, I>)
class subrange

    : public ranges::view_interface<subrange<I, S, K>>
(1) (since C++20)
Helper concepts
template<class From, class To>

concept /*uses-nonqualification-pointer-conversion*/ =

    /* see description */;
(2) (exposition only*)
template<class From, class To>
concept /*convertible-to-non-slicing*/ = /* see description */;
(3) (exposition only*)
1) The subrange class template combines together an iterator and a sentinel into a single view. It models sized_range whenever the final template parameter is subrange_kind​::​sized (which happens when std::sized_sentinel_for<S, I> is satisfied or when size is passed explicitly as a constructor argument).
2) Determintes whether From is convertible to To without qualification conversions. Equivalent to:
template<class From, class To>
concept /*uses-nonqualification-pointer-conversion*/ =
    std::is_pointer_v<From> && std::is_pointer_v<To> &&
        !std::convertible_to<std::remove_pointer_t<From>(*)[],
                             std::remove_pointer_t<To>(*)[]>;
3) Determintes whether From is convertible to To without derived-to-base conversion:
template<class From, class To>
concept /*convertible-to-non-slicing*/ =
    std::convertible_to<From, To> &&
        !/*uses-nonqualification-pointer-conversion*/
            <std::decay_t<From>, std::decay_t<To>>;

Data members

Member Definition
constexpr bool StoreSize [static] K == ranges::subrange_kind::sized &&
    !std::sized_sentinel_for<S, I>

(exposition-only static member constant*)
I begin_ an iterator to the beginning of the subrange
(exposition-only member object*)
S end_ a sentinel denoting the end of the subrange
(exposition-only member object*)
make-unsigned-like-t <std::iter_difference_t<I>> size_
(present only if StoreSize is true)
the size of the subrange
(exposition-only member object*)

Member functions

creates a new subrange
(public member function)
converts the subrange to a pair-like type
(public member function)
Observers
obtains the iterator
(public member function)
obtains the sentinel
(public member function)
checks whether the subrange is empty
(public member function)
obtains the size of the subrange
(public member function)
Iterator operations
advances the iterator by given distance
(public member function)
obtains a copy of the subrange with its iterator decremented by a given distance
(public member function)
obtains a copy of the subrange with its iterator advanced by a given distance
(public member function)
Inherited from std::ranges::view_interface
(C++23)
returns a constant iterator to the beginning of the range.
(public member function of std::ranges::view_interface<D>)
(C++23)
returns a sentinel for the constant iterator of the range.
(public member function of std::ranges::view_interface<D>)
returns whether the derived view is not empty. Provided if ranges::empty is applicable to it.
(public member function of std::ranges::view_interface<D>)
gets the address of derived view's data. Provided if its iterator type satisfies contiguous_iterator.
(public member function of std::ranges::view_interface<D>)
returns the first element in the derived view. Provided if it satisfies forward_range.
(public member function of std::ranges::view_interface<D>)
returns the last element in the derived view. Provided if it satisfies bidirectional_range and common_range.
(public member function of std::ranges::view_interface<D>)
returns the nth element in the derived view. Provided if it satisfies random_access_range.
(public member function of std::ranges::view_interface<D>)

Deduction guides

Non-member functions

obtains iterator or sentinel from a std::ranges::subrange
(function template)

Helper types

specifies whether a std::ranges::subrange models std::ranges::sized_range
(enum)
obtains the size of a std::ranges::subrange
(class template specialization)
obtains the type of the iterator or the sentinel of a std::ranges::subrange
(class template specialization)

Helper templates

template< class I, class S, ranges::subrange_kind K >
constexpr bool ranges::enable_borrowed_range<ranges::subrange<I, S, K>> = true;
(since C++20)

This specialization of ranges::enable_borrowed_range makes subrange satisfy borrowed_range.

Example

#include <map>
#include <print>
#include <ranges>
 
void make_uppercase(char& v)
{
    v += 'A' - 'a';
}
 
void uppercase_transform(std::multimap<int, char>& m, int k)
{
    auto [first, last] = m.equal_range(k);
    for (auto& [_, v] : std::ranges::subrange(first, last))
        make_uppercase(v);
}
 
int main()
{
    std::multimap<int, char> mm{{4, 'a'}, {3, '-'}, {4, 'b'}, {5, '-'}, {4, 'c'}};
    std::println("Before: {}", mm);
    uppercase_transform(mm, 4);
    std::println("After:  {}", mm);
}

Output:

Before: {3: '-', 4: 'a', 4: 'b', 4: 'c', 5: '-'}
After:  {3: '-', 4: 'A', 4: 'B', 4: 'C', 5: '-'}

Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 3470 C++20 convertible-to-non-slicing might reject qualification conversions always accepts them

See also

helper class template for defining a view, using the curiously recurring template pattern
(class template)

External links

Read/write all values of a std::multimap with a given key in C++20 — SO