26 Ranges library [ranges]

26.5 Range utilities [range.utility]

26.5.3 View interface [view.interface]

26.5.3.1 General [view.interface.general]

The class template view_­interface is a helper for defining view-like types that offer a container-like interface.
It is parameterized with the type that is derived from it.
namespace std::ranges { template<class D> requires is_class_v<D> && same_­as<D, remove_cv_t<D>> class view_interface { private: constexpr D& derived() noexcept { // exposition only return static_cast<D&>(*this); } constexpr const D& derived() const noexcept { // exposition only return static_cast<const D&>(*this); } public: constexpr bool empty() requires sized_­range<D> || forward_­range<D> { if constexpr (sized_­range<D>) return ranges::size(derived()) == 0; else return ranges::begin(derived()) == ranges::end(derived()); } constexpr bool empty() const requires sized_­range<const D> || forward_­range<const D> { if constexpr (sized_­range<const D>) return ranges::size(derived()) == 0; else return ranges::begin(derived()) == ranges::end(derived()); } constexpr auto cbegin() { return ranges::cbegin(derived()); } constexpr auto cbegin() const requires range<const D> { return ranges::cbegin(derived()); } constexpr auto cend() { return ranges::cend(derived()); } constexpr auto cend() const requires range<const D> { return ranges::cend(derived()); } constexpr explicit operator bool() requires requires { ranges::empty(derived()); } { return !ranges::empty(derived()); } constexpr explicit operator bool() const requires requires { ranges::empty(derived()); } { return !ranges::empty(derived()); } constexpr auto data() requires contiguous_­iterator<iterator_t<D>> { return to_address(ranges::begin(derived())); } constexpr auto data() const requires range<const D> && contiguous_­iterator<iterator_t<const D>> { return to_address(ranges::begin(derived())); } constexpr auto size() requires forward_­range<D> && sized_­sentinel_­for<sentinel_t<D>, iterator_t<D>> { return ranges::end(derived()) - ranges::begin(derived()); } constexpr auto size() const requires forward_­range<const D> && sized_­sentinel_­for<sentinel_t<const D>, iterator_t<const D>> { return ranges::end(derived()) - ranges::begin(derived()); } constexpr decltype(auto) front() requires forward_­range<D>; constexpr decltype(auto) front() const requires forward_­range<const D>; constexpr decltype(auto) back() requires bidirectional_­range<D> && common_­range<D>; constexpr decltype(auto) back() const requires bidirectional_­range<const D> && common_­range<const D>; template<random_­access_­range R = D> constexpr decltype(auto) operator[](range_difference_t<R> n) { return ranges::begin(derived())[n]; } template<random_­access_­range R = const D> constexpr decltype(auto) operator[](range_difference_t<R> n) const { return ranges::begin(derived())[n]; } }; }
The template parameter D for view_­interface may be an incomplete type.
Before any member of the resulting specialization of view_­interface other than special member functions is referenced, D shall be complete, and model both derived_­from<view_­interface<D>> and view.

26.5.3.2 Members [view.interface.members]

constexpr decltype(auto) front() requires forward_­range<D>; constexpr decltype(auto) front() const requires forward_­range<const D>;
Preconditions: !empty() is true.
Effects: Equivalent to: return *ranges​::​begin(derived());
constexpr decltype(auto) back() requires bidirectional_­range<D> && common_­range<D>; constexpr decltype(auto) back() const requires bidirectional_­range<const D> && common_­range<const D>;
Preconditions: !empty() is true.
Effects: Equivalent to: return *ranges​::​prev(ranges​::​end(derived()));