std::ranges...s::view_base(3)

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

okay bestie, you just opened the std::ranges...s::view_base(3) page from the C++ Standard Libary and we're gonna make it make sense πŸ’– this is the group chat where view, enable_view, and view_base all get their moment.

πŸ’– NAME πŸ’–

std::ranges::view,std::ranges::enable_view,std::ranges::view_base β€” and the one-liner is literally std::ranges::view,std::ranges::enable_view,std::ranges::view_base πŸ’… the iconic trio, no cap.

✨ Synopsis ✨

Defined in header <ranges> β€” put that in your notes, bestie πŸŽ€

          Defined in header <ranges>
          template<class T>
          concept view = ranges::range<T> && std::movable<T> &&
       (1) (since C++20)
          ranges::enable_view<T>;
          template<class T>

          inline constexpr bool enable_view =
       (2) (since C++20)

              std::derived_from<T, view_base> ||
          /*is-derived-from-view-interface*/<T>;
          struct view_base { };
       (3) (since C++20)
  1. The view concept specifies the requirements of a range type that has suitable semantic properties for use in constructing range adaptor pipelines. (since C++20) πŸ¦‹
  2. The enable_view variable template is used to indicate whether a range is a view. (since C++20) /*is-derived-from-view-interface*/<T> is true if and only if T has exactly one public base class ranges::view_interface<U> for some type U, and T has no base classes of type ranges::view_interface<V> for any other type V. Users may specialize enable_view to true for cv-unqualified program-defined types which model view, and false for types which do not. Such specializations must be usable in constant expressions and have type const bool. πŸ’…
  3. Deriving from view_base enables range types to model view. (since C++20) ✨

πŸ¦‹ Notes πŸ¦‹

Examples of view types are:

  • A range type that wraps a pair of iterators, e.g., std::ranges::subrange<I>.
  • A range type that holds its elements by std::shared_ptr and shares ownership with all its copies.
  • A range type that generates its elements on demand, e.g., std::ranges::iota_view.

A copyable container such as std::vector<std::string> generally does not meet the semantic requirements of view since copying the container copies all of the elements, which cannot be done in constant time. 😭

While views were originally described as cheaply copyable and non-owning ranges, a type is not required to be copyable or non-owning for it to model view. However, it must still be cheap to copy (if it is copyable), move, assign, and destroy, so that range adaptors will not have unexpected complexity. fr fr 🫢

By default, a type modeling movable and range is considered a view if it is publicly and unambiguously derived from view_base, or exactly one specialization of std::ranges::view_interface. 🌈

πŸ“ Example πŸ“

A minimum view.

#include <ranges>

struct ArchetypalView : std::ranges::view_interface<ArchetypalView>
{
    int* begin();
    int* end();
};

static_assert(std::ranges::view<ArchetypalView>);

πŸ’€ Defect reports πŸ’€

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

  • P2325R3 β€” applied to C++20. Behavior as published: view required default_initializable. Correct behavior: does not require.
  • LWG 3549 β€” applied to C++20. Behavior as published: enable_view did not detect inheritance from view_interface. Correct behavior: detects.
  • P2415R2 β€” applied to C++20. Behavior as published: the restriction on the time complexity of destruction was too strict. Correct behavior: relaxed.

shoutout to http://cppreference.com β€” version 2024.06.10 β€” for std::ranges...s::view_base(3). mwah πŸ’‹

πŸ“¦ where this page comes from