std::ranges::subrange<I,S,K>::operator PairLike

From cppreference.com
< cpp‎ | ranges‎ | subrange
 
 
Ranges library
Range access
Range conversions
(C++23)
Range primitives



Dangling iterator handling
Range concepts
Views

Factories






Adaptors
Range adaptor objects
Range adaptor closure objects
Helper items
 
std::ranges::subrange
Member functions
subrange::operator PairLike
(C++20)
Observers
Iterator operations
Deduction guides
Non-member functions
(C++20)
Helper types
(C++20)
 
template< /*different-from*/<subrange> PairLike >

    requires /*pair-like-convertible-from*/<PairLike, const I&, const S&>

constexpr operator PairLike() const;
(1) (since C++20)
Helper concepts
template< class T >

concept /*pair-like*/ =                  // exposition only
  !std::is_reference_v<T> && requires(T t) {
    typename std::tuple_size<T>::type;   // ensures std::tuple_size<T> is complete
    requires std::derived_from<std::tuple_size<T>,
                               std::integral_constant<std::size_t, 2>>;
    typename std::tuple_element_t<0, std::remove_const<T>>;
    typename std::tuple_element_t<1, std::remove_const<T>>;
    { std::get<0>(t) } -> std::convertible_to<const std::tuple_element_t<0, T>&>;
    { std::get<1>(t) } -> std::convertible_to<const std::tuple_element_t<1, T>&>;

  };
(2) (since C++20)
template< class T, class U, class V >

concept /*pair-like-convertible-from*/ = // exposition only
  !ranges::range<T> && /*pair-like*/<T> &&
  std::constructible_from<T, U, V> &&
  /*convertible-to-non-slicing*/<U, std::tuple_element_t<0, T>> &&

  std::convertible_to<V, std::tuple_element_t<1, T>>;
(3) (since C++20)
1) Converts subrange to a pair-like type (i.e. a type models pair-like, see below). Equivalent to return PairLike(i_, s_);, where i_ and s_ are the stored iterator and sentinel respectively. This conversion function has additional constraints imposed by pair-like-convertible (see below).
2) The exposition-only concept pair-like specifies a type is pair-like. Generally, an expression e of a pair-like type can be used for structured binding (i.e. auto const& [x, y] = e; is generally well-formed). Like standard concepts, this concept is modeled if it is satisfied and all concepts it subsumes are modeled.
3) The exposition-only concept pair-like-convertible-from refines pair-like. It rejects range types and requires that U and V are convertible to the first and second element type of T respectively, and the conversion from U (which will be replaced by const I&) to the first element type is non-slicing (see convertible-to-non-slicing). Like standard concepts, this concept is modeled if it is satisfied and all concepts it subsumes are modeled.

The exposition only concept different-from is modeled by types T and U if and only if std::decay_t<T> and std::decay_t<U> are different types.

Parameters

(none)

Return value

A PairLike value direct-initialized with the stored iterator and sentinel.

Notes

Following types in the standard library are pair-like:

A program-defined type derived from one of these types can be a pair-like type, if

  • std::tuple_size and std::tuple_element are correctly specialized for it, and
  • calls to std::get<0> and std::get<1> for its value are well-formed.

Since subrange specializations are range types, conversion to them are not performed via this conversion function.

std::array specializations cannot be converted from subrange, since they are range types.

Example

#include <iostream>
#include <ranges>
#include <string>
#include <utility>
 
using legacy_strview = std::pair<
    std::string::const_iterator,
    std::string::const_iterator
>;
 
void legacy_print(legacy_strview p)
{
    for (; p.first != p.second; ++p.first)
        std::cout << *p.first << ' ';
    std::cout << '\n';
}
 
int main()
{
    std::string dat{"ABCDE"};
    for (auto v{ std::ranges::subrange{dat} }; v; v = {v.begin(), v.end() - 1}) {
        /*...*/
        legacy_print(legacy_strview{v});
    }
}

Output:

A B C D E 
A B C D 
A B C 
A B 
A