std::ranges...ge::subrange(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… std::ranges::subrange::subrange πŸ’…

okay so bestie, welcome to the C++ Standard Libary manual β€” and yes, the header really spells it Libary, iconic behavior. The header title is std::ranges...ge::subrange(3), and this whole page is about the constructors of std::ranges::subrange. Buckle up, we’re building subranges πŸŽ€.


🌸 NAME 🌸

std::ranges::subrange::subrange β€” std::ranges::subrange::subrange


✨ Synopsis ✨

okay so here’s the constructor buffet. The little numbers (1) through (5) are the manpage’s labels, and the (since C++20) notes are kept too:

subrange() requires std::default_initializable<I> = default;                         // (1) (since C++20)

constexpr subrange( /*convertible-to-non-slicing*/<I> auto i, S s )                  // (2) (since C++20)
    requires (!/*store-size*/);

constexpr subrange( /*convertible-to-non-slicing*/<I> auto i, S s,
                    /*make-unsigned-like-t*/<std::iter_difference_t<I>> n )          // (3) (since C++20)
    requires (K == ranges::subrange_kind::sized);

template< /*different-from*/<subrange> R >
    requires ranges::borrowed_range<R> &&
             /*convertible-to-non-slicing*/<ranges::iterator_t<R>, I> &&
             std::convertible_to<ranges::sentinel_t<R>, S>
constexpr subrange( R&& r )                                                           // (4) (since C++20)
    requires (!/*store-size*/ || ranges::sized_range<R>);

template< ranges::borrowed_range R>
    requires /*convertible-to-non-slicing*/<ranges::iterator_t<R>, I> &&
             std::convertible_to<ranges::sentinel_t<R>, S>
constexpr subrange( R&& r,
                    /*make-unsigned-like-t*/<std::iter_difference_t<I>> n )          // (5) (since C++20)
    requires (K == ranges::subrange_kind::sized)
        : subrange{ranges::begin(r), ranges::end(r), n}
{}

Constructs a subrange. 🫢

So here’s the tea: if K == ranges::subrange_kind::sized && !std::sized_sentinel_for<S, I>, the size of the range is stored into the subrange, as if stored by a member subobject of type /*make-unsigned-like-t*/<std::iter_difference_t<I>>, where make-unsigned-like-t is an exposition-only alias template that maps each integer-like type to its corresponding unsigned version. Otherwise, the size is not stored. The constant store-size is true if the size is stored, false otherwise. No cap.

  1. Default constructor. Value-initializes the stored iterator and sentinel as if by default member initializers = I() and = S(), respectively. If the size is stored, it is initialized with 0 as if by the default member initializer = 0.
  2. Constructs a subrange from an iterator-sentinel pair. Initializes the stored iterator and sentinel with std::move(i) and s respectively. The behavior is undefined if [i, s) is not a valid range.
  3. Constructs a subrange from an iterator-sentinel pair and a size hint. Initializes the stored iterator and sentinel with std::move(i) and s respectively. If the size is stored, it is initialized with n. The behavior is undefined if [i, s) is not a valid range, or n is not equal to ranges::distance(i, s) explicitly converted to its type.
  4. Constructs a subrange from a range. Equivalent to subrange(r, static_cast</*make-unsigned-like-t*/<std::iter_difference_t<I>>>(ranges::size(r))) if the size is stored. Otherwise, equivalent to subrange(ranges::begin(r), ranges::end(r)).
  5. Constructs a subrange from a range and a size hint. The behavior is undefined if n is not equal to ranges::distance(ranges::begin(r), ranges::end(r)) explicitly converted to its type.

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.

The exposition-only concept convertible-to-non-slicing is satisfied or modeled by From and To if and only if std::convertible_to<From, To> is satisfied or modeled respectively, and any of the following conditions is satisfied:

  • either std::decay_t<From> or std::decay_t<To> is not a pointer type,
  • std::remove_pointer_t<From>(*)[] is implicitly convertible to std::remove_pointer_t<To>(*)[], i.e., the conversion from From to To is at most a qualification conversion.

πŸŽ€ Parameters πŸŽ€

  • i β€” iterator that denotes the beginning of the range.
  • s β€” sentinel that denotes the end of the range.
  • r β€” range.
  • n β€” size hint, must be equal to the size of the range.

πŸ’… Notes πŸ’…

The exposition-only concept convertible-to-non-slicing forbids the conversion from the pointer to derived class to the pointer to base class. That’s the whole warning, bestie β€” do not slice those pointers 🫢.

πŸ¦‹ Defect reports πŸ¦‹

The following behavior-changing defect reports were applied retroactively to previously published C++ standards. The manpage columns are DR, Applied to, Behavior as published, and Correct behavior:

  • LWG 3470 β€” Applied to: C++20. Behavior as published: convertible-to-non-slicing rejected some valid qualification conversions. Correct behavior: made accepted.
  • P2393R1 β€” Applied to: C++20. Behavior as published: implicit conversion to an integer-class type might be invalid. Correct behavior: made explicit.

🌈 Example 🌈

This section is incomplete.

Reason: no example.


πŸ“ Category πŸ“

  • Todo no example

okay that’s the whole page, bestie! The footer says source/version http://cppreference.com and date 2024.06.10, with the page title std::ranges...ge::subrange(3). Stay glittery, and may your constructors always match their constraints πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from