24 Ranges library [ranges]

24.4 Range requirements [range.req]

24.4.4 Views [range.view]

The view concept specifies the requirements of a range type that has the semantic properties below, which make it suitable for use in constructing range adaptor pipelines ([range.adaptors]).
template<class T> concept view = range<T> && movable<T> && enable_view<T>;
T models view only if:
  • T has move construction; and
  • move assignment of an object of type T is no more complex than destruction followed by move construction; and
  • if N copies and/or moves are made from an object of type T that contained M elements, then those N objects have destruction
    [Note 1:
    This implies that a moved-from object of type T has destruction
    — end note]
    ; and
  • copy_­constructible<T> is false, or T has copy construction; and
  • copyable<T> is false, or copy assignment of an object of type T is no more complex than destruction followed by copy construction.
[Example 1:
Examples of views are:
  • A range type that wraps a pair of iterators.
  • A range type that holds its elements by shared_­ptr and shares ownership with all its copies.
  • A range type that generates its elements on demand.
A container such as vector<string> does not meet the semantic requirements of view since copying the container copies all of the elements, which cannot be done in constant time.
— end example]
Since the difference between range and view is largely semantic, the two are differentiated with the help of enable_­view.
template<class T> inline constexpr bool is-derived-from-view-interface = see below; // exposition only template<class T> inline constexpr bool enable_view = derived_­from<T, view_base> || is-derived-from-view-interface<T>;
For a type T, is-derived-from-view-interface<T> is true if and only if T has exactly one public base class view_­interface<U> for some type U and T has no base classes of type view_­interface<V> for any other type V.
Remarks: Pursuant to [namespace.std], 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 shall be usable in constant expressions ([expr.const]) and have type const bool.